RetroZilla/xpinstall/wizard/windows/test/delayRemove.c
2015-10-20 23:03:22 -04:00

243 lines
7.5 KiB
C

#include <windows.h>
#include <stdio.h>
#define MAX_BUF 1024
#define LEN_DELAYED_DELETE_PREFIX lstrlen("\\??\\")
void PrintSpecial(char *string, int stringBufSize);
void PrintSpecial(char *string, int stringBufSize)
{
int i;
int nullCount = 0;
printf("\nlength: %d\n", stringBufSize);
for(i = 0; i < stringBufSize; i++)
{
if(string[i] == '\0')
{
printf("{null}");
nullCount++;
}
else
printf("%c", string[i]);
}
}
void RemoveDelayedDeleteFileEntries(const char *aPathToMatch)
{
HKEY hkResult;
DWORD dwErr;
DWORD dwType = REG_NONE;
DWORD oldMaxValueLen = 0;
DWORD newMaxValueLen = 0;
DWORD lenToEnd = 0;
char *multiStr = NULL;
const char key[] = "SYSTEM\\CurrentControlSet\\Control\\Session Manager";
const char name[] = "PendingFileRenameOperations";
char *pathToMatch;
char *lcName;
char *pName;
char *pRename;
int nameLen, renameLen;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ|KEY_WRITE, &hkResult) != ERROR_SUCCESS)
return;
dwErr = RegQueryValueEx(hkResult, name, 0, &dwType, NULL, &oldMaxValueLen);
if (dwErr != ERROR_SUCCESS || oldMaxValueLen == 0 || dwType != REG_MULTI_SZ)
{
/* no value, no data, or wrong type */
return;
}
multiStr = calloc(oldMaxValueLen, sizeof(BYTE));
if (!multiStr)
return;
pathToMatch = strdup(aPathToMatch);
if (!pathToMatch)
{
free(multiStr);
return;
}
if (RegQueryValueEx(hkResult, name, 0, NULL, multiStr, &oldMaxValueLen) == ERROR_SUCCESS)
{
PrintSpecial(multiStr, oldMaxValueLen);
// The registry value consists of name/newname pairs of null-terminated
// strings, with a final extra null termination. We're only interested
// in files to be deleted, which are indicated by a null newname.
_mbslwr(pathToMatch);
lenToEnd = newMaxValueLen = oldMaxValueLen;
pName = multiStr;
while(*pName && lenToEnd > 0)
{
// find the locations and lengths of the current pair. Count the
// nulls, we need to know how much data to skip or move
nameLen = strlen(pName) + 1;
pRename = pName + nameLen;
renameLen = strlen(pRename) + 1;
// How much remains beyond the current pair
lenToEnd -= (nameLen + renameLen);
if (*pRename == '\0')
{
// No new name, it's a delete. Is it the one we want?
lcName = strdup(pName);
if (lcName)
{
_mbslwr(lcName);
if (strstr(lcName, pathToMatch))
{
// It's a match--
// delete this pair by moving the remainder on top
memmove(pName, pRename + renameLen, lenToEnd);
// update the total length to reflect the missing pair
newMaxValueLen -= (nameLen + renameLen);
// next pair is in place, continue w/out moving pName
continue;
}
}
}
// on to the next pair
pName = pRename + renameLen;
}
if (newMaxValueLen != oldMaxValueLen)
{
PrintSpecial(multiStr, newMaxValueLen);
// We've deleted something, save the changed data
RegSetValueEx(hkResult, name, 0, REG_MULTI_SZ, multiStr, newMaxValueLen);
RegFlushKey(hkResult);
}
}
RegCloseKey(hkResult);
free(multiStr);
}
#if 0
void RemoveDelayedDeleteFileEntries(const char *aPathToMatch)
{
HKEY hkResult;
DWORD dwErr;
DWORD oldMaxValueLen = 0;
DWORD newMaxValueLen = 0;
int lenToEnd = 0;
char buf[MAX_BUF];
char *pathToMatch = NULL;
char *multiStr = NULL;
char key[] = "SYSTEM\\CurrentControlSet\\Control\\Session Manager";
char name[] = "PendingFileRenameOperations";
char *op;
char *np;
char *beginPath;
BOOL done = FALSE;
pathToMatch = strdup(aPathToMatch);
if(!pathToMatch)
return;
if((dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ|KEY_WRITE, &hkResult)) == ERROR_SUCCESS)
{
dwErr = RegQueryValueEx(hkResult, name, 0, NULL, NULL, &oldMaxValueLen);
printf("maxValueLen0: %d\n", oldMaxValueLen);
multiStr = calloc(oldMaxValueLen, sizeof(BYTE));
dwErr = RegQueryValueEx(hkResult, name, 0, NULL, multiStr, &oldMaxValueLen);
printf("maxValueLen1: %d\n", oldMaxValueLen);
if(dwErr != ERROR_SUCCESS)
printf("RegQueryValueEx() failed: %d\n", dwErr);
PrintSpecial(multiStr, oldMaxValueLen);
lenToEnd = newMaxValueLen = oldMaxValueLen;
op = multiStr;
if(op && (oldMaxValueLen > 4))
{
_mbslwr(pathToMatch);
while(!done)
{
beginPath = op + LEN_DELAYED_DELETE_PREFIX; // skip the first 4 chars ('\\??\\') to get to the first char of path;
np = beginPath + lstrlen(beginPath) + 1;
lstrcpy(buf, beginPath);
_mbslwr(buf);
lenToEnd = lenToEnd - lstrlen(op) + 2 - LEN_DELAYED_DELETE_PREFIX; // reset the lenToEnd
if(strstr(buf, pathToMatch))
{
if(*np == '\0') // delete found
{
newMaxValueLen = newMaxValueLen - lstrlen(op) + 2 - LEN_DELAYED_DELETE_PREFIX; // reset the newMaxValueLen
memmove(op, np + 1, lenToEnd);
}
else // rename found. do nothing for renaming
{
printf("len of np: %d\n", lstrlen(np));
lenToEnd = lenToEnd - lstrlen(np); // reset the lenToEnd
op = np + lstrlen(np) + 1;
}
}
else if(*np != '\0')
{
lenToEnd = lenToEnd - lstrlen(np); // reset the lenToEnd
op = np + lstrlen(np) + 1;
}
else
op = np + 1;
if(*op == '\0') // terminating NULL byte indicating end of MULTISZ
done = TRUE;
}
}
PrintSpecial(multiStr, newMaxValueLen);
dwErr = RegSetValueEx(hkResult,
name,
0,
REG_MULTI_SZ,
multiStr,
newMaxValueLen);
if(dwErr != ERROR_SUCCESS)
printf("RegQueryValueEx() failed: %d\n", dwErr);
if(multiStr)
free(multiStr);
RegFlushKey(hkResult);
RegCloseKey(hkResult);
}
if(pathToMatch)
free(pathToMatch);
}
#endif
int main(argc, argv)
{
char buf[MAX_BUF];
DWORD bufSize = sizeof(buf);
// MoveFileEx("c:\\windows\\system32\\mapistubs.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx("c:\\program files\\aol communicator\\phidlemon.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
// MoveFileEx("c:\\windows\\system32\\mapistubs.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx("c:\\prOGRAM fILES\\aol COMMUNicator\\phidlemon.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
// MoveFileEx("c:\\windows\\system32\\mapistubs.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx("srcfiletoremane.txt", "dstfilerenamed.txt", MOVEFILE_DELAY_UNTIL_REBOOT);
// MoveFileEx("c:\\windows\\system32\\mapistubs.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx("c:\\program files\\aol communicator\\phidlemon.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
// MoveFileEx("c:\\windows\\system32\\mapistubs.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx("c:\\program files\\aol communicator\\phidlemon.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
// MoveFileEx("c:\\windows\\system32\\mapistubs.dll", NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
MoveFileEx("srcfiletorename.txt", "dstfilerenamed.txt", MOVEFILE_DELAY_UNTIL_REBOOT);
RemoveDelayedDeleteFileEntries("C:\\Program Files\\AOL Communicator\\");
}