#include "gptext.h" //************************************************************* // // CheckSlash() // // Purpose: Checks for an ending slash and adds one if // it is missing. // // Parameters: lpDir - directory // // Return: Pointer to the end of the string // // Comments: // // History: Date Author Comment // 6/19/95 ericflo Created // //************************************************************* LPTSTR CheckSlash (LPTSTR lpDir) { LPTSTR lpEnd; lpEnd = lpDir + lstrlen(lpDir); if (*(lpEnd - 1) != TEXT('\\')) { *lpEnd = TEXT('\\'); lpEnd++; *lpEnd = TEXT('\0'); } return lpEnd; } //************************************************************* // // RegDelnodeRecurse() // // Purpose: Deletes a registry key and all it's subkeys / values. // Called by RegDelnode // // Parameters: hKeyRoot - Root key // lpSubKey - SubKey to delete // // Return: TRUE if successful // FALSE if an error occurs // // Comments: // // History: Date Author Comment // 10/3/95 ericflo Created // //************************************************************* BOOL RegDelnodeRecurse (HKEY hKeyRoot, LPTSTR lpSubKey) { LPTSTR lpEnd; LONG lResult; DWORD dwSize; TCHAR szName[MAX_PATH]; HKEY hKey; FILETIME ftWrite; // // First, see if we can delete the key without having // to recurse. // lResult = RegDeleteKey(hKeyRoot, lpSubKey); if (lResult == ERROR_SUCCESS) { return TRUE; } lResult = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey); if (lResult != ERROR_SUCCESS) { return FALSE; } lpEnd = CheckSlash(lpSubKey); // // Enumerate the keys // dwSize = MAX_PATH; lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite); if (lResult == ERROR_SUCCESS) { do { lstrcpy (lpEnd, szName); if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) { break; } // // Enumerate again // dwSize = MAX_PATH; lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL, NULL, NULL, &ftWrite); } while (lResult == ERROR_SUCCESS); } lpEnd--; *lpEnd = TEXT('\0'); RegCloseKey (hKey); // // Try again to delete the key // lResult = RegDeleteKey(hKeyRoot, lpSubKey); if (lResult == ERROR_SUCCESS) { return TRUE; } return FALSE; } //************************************************************* // // RegDelnode() // // Purpose: Deletes a registry key and all it's subkeys / values // // Parameters: hKeyRoot - Root key // lpSubKey - SubKey to delete // // Return: TRUE if successful // FALSE if an error occurs // // Comments: // // History: Date Author Comment // 10/3/95 ericflo Created // //************************************************************* BOOL RegDelnode (HKEY hKeyRoot, LPTSTR lpSubKey) { TCHAR szDelKey[2 * MAX_PATH]; lstrcpy (szDelKey, lpSubKey); return RegDelnodeRecurse(hKeyRoot, szDelKey); } //************************************************************* // // RegCleanUpValue() // // Purpose: Removes the target value and if no more values / keys // are present, removes the key. This function then // works up the parent tree removing keys if they are // also empty. If any parent key has a value / subkey, // it won't be removed. // // Parameters: hKeyRoot - Root key // lpSubKey - SubKey // lpValueName - Value to remove // // // Return: TRUE if successful // FALSE if an error occurs // //************************************************************* BOOL RegCleanUpValue (HKEY hKeyRoot, LPTSTR lpSubKey, LPTSTR lpValueName) { TCHAR szDelKey[2 * MAX_PATH]; LPTSTR lpEnd; DWORD dwKeys, dwValues; LONG lResult; HKEY hKey; // // Make a copy of the subkey so we can write to it. // lstrcpy (szDelKey, lpSubKey); // // First delete the value // lResult = RegOpenKeyEx (hKeyRoot, szDelKey, 0, KEY_WRITE, &hKey); if (lResult == ERROR_SUCCESS) { lResult = RegDeleteValue (hKey, lpValueName); RegCloseKey (hKey); if (lResult != ERROR_SUCCESS) { if (lResult != ERROR_FILE_NOT_FOUND) { DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to delete value <%s> with %d."), lpValueName, lResult)); return FALSE; } } } // // Now loop through each of the parents. If the parent is empty // eg: no values and no other subkeys, then remove the parent and // keep working up. // lpEnd = szDelKey + lstrlen(szDelKey) - 1; while (lpEnd >= szDelKey) { // // Find the parent key // while ((lpEnd > szDelKey) && (*lpEnd != TEXT('\\'))) lpEnd--; // // Open the key // lResult = RegOpenKeyEx (hKeyRoot, szDelKey, 0, KEY_READ, &hKey); if (lResult != ERROR_SUCCESS) { if (lResult == ERROR_FILE_NOT_FOUND) { goto LoopAgain; } else { DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to open key <%s> with %d."), szDelKey, lResult)); return FALSE; } } // // See if there any any values / keys // lResult = RegQueryInfoKey (hKey, NULL, NULL, NULL, &dwKeys, NULL, NULL, &dwValues, NULL, NULL, NULL, NULL); RegCloseKey (hKey); if (lResult != ERROR_SUCCESS) { DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to query key <%s> with %d."), szDelKey, lResult)); return FALSE; } // // Exit now if this key has values or keys // if ((dwKeys != 0) || (dwValues != 0)) { return TRUE; } RegDeleteKey (hKeyRoot, szDelKey); LoopAgain: // // If we are at the beginning of the subkey, we can leave now. // if (lpEnd == szDelKey) { return TRUE; } // // There is a parent key. Remove the slash and loop again. // if (*lpEnd == TEXT('\\')) { *lpEnd = TEXT('\0'); } } return TRUE; } //************************************************************* // // CreateNestedDirectory() // // Purpose: Creates a subdirectory and all it's parents // if necessary. // // Parameters: lpDirectory - Directory name // lpSecurityAttributes - Security Attributes // // Return: > 0 if successful // 0 if an error occurs // // Comments: // // History: Date Author Comment // 8/08/95 ericflo Created // //************************************************************* UINT CreateNestedDirectory(LPCTSTR lpDirectory, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { TCHAR szDirectory[MAX_PATH]; LPTSTR lpEnd; // // Check for NULL pointer // if (!lpDirectory || !(*lpDirectory)) { DebugMsg((DM_WARNING, TEXT("CreateNestedDirectory: Received a NULL pointer."))); return 0; } // // First, see if we can create the directory without having // to build parent directories. // if (CreateDirectory (lpDirectory, lpSecurityAttributes)) { return 1; } // // If this directory exists already, this is OK too. // if (GetLastError() == ERROR_ALREADY_EXISTS) { return ERROR_ALREADY_EXISTS; } // // No luck, copy the string to a buffer we can munge // lstrcpy (szDirectory, lpDirectory); // // Find the first subdirectory name // lpEnd = szDirectory; if (szDirectory[1] == TEXT(':')) { lpEnd += 3; } else if (szDirectory[1] == TEXT('\\')) { // // Skip the first two slashes // lpEnd += 2; // // Find the slash between the server name and // the share name. // while (*lpEnd && *lpEnd != TEXT('\\')) { lpEnd++; } if (!(*lpEnd)) { return 0; } // // Skip the slash, and find the slash between // the share name and the directory name. // lpEnd++; while (*lpEnd && *lpEnd != TEXT('\\')) { lpEnd++; } if (!(*lpEnd)) { return 0; } // // Leave pointer at the beginning of the directory. // lpEnd++; } else if (szDirectory[0] == TEXT('\\')) { lpEnd++; } while (*lpEnd) { while (*lpEnd && *lpEnd != TEXT('\\')) { lpEnd++; } if (*lpEnd == TEXT('\\')) { *lpEnd = TEXT('\0'); if (!CreateDirectory (szDirectory, NULL)) { if (GetLastError() != ERROR_ALREADY_EXISTS) { DebugMsg((DM_WARNING, TEXT("CreateNestedDirectory: CreateDirectory failed with %d."), GetLastError())); return 0; } } *lpEnd = TEXT('\\'); lpEnd++; } } // // Create the final directory // if (CreateDirectory (szDirectory, lpSecurityAttributes)) { return 1; } if (GetLastError() == ERROR_ALREADY_EXISTS) { return ERROR_ALREADY_EXISTS; } // // Failed // DebugMsg((DM_VERBOSE, TEXT("CreateNestedDirectory: Failed to create the directory with error %d."), GetLastError())); return 0; } /******************************************************************* NAME: StringToNum SYNOPSIS: Converts string value to numeric value NOTES: Calls atoi() to do conversion, but first checks for non-numeric characters EXIT: Returns TRUE if successful, FALSE if invalid (non-numeric) characters ********************************************************************/ BOOL StringToNum(TCHAR *pszStr,UINT * pnVal) { TCHAR *pTst = pszStr; if (!pszStr) return FALSE; // verify that all characters are numbers while (*pTst) { if (!(*pTst >= TEXT('0') && *pTst <= TEXT('9'))) { // if (*pTst != TEXT('-')) return FALSE; } pTst = CharNext(pTst); } *pnVal = _ttoi(pszStr); return TRUE; } //************************************************************* // // ImpersonateUser() // // Purpose: Impersonates the specified user // // Parameters: hToken - user to impersonate // // Return: hToken if successful // FALSE if an error occurs // //************************************************************* BOOL ImpersonateUser (HANDLE hNewUser, HANDLE *hOldUser) { if (!OpenThreadToken (GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_READ, TRUE, hOldUser)) { *hOldUser = NULL; } if (!ImpersonateLoggedOnUser(hNewUser)) { if ( *hOldUser ) { CloseHandle( *hOldUser ); *hOldUser = NULL; } DebugMsg((DM_WARNING, TEXT("ImpersonateUser: Failed to impersonate user with %d."), GetLastError())); return FALSE; } return TRUE; } //************************************************************* // // RevertToUser() // // Purpose: Revert back to original user // // Parameters: hUser - original user token // // Return: TRUE if successful // FALSE if an error occurs // //************************************************************* BOOL RevertToUser (HANDLE *hUser) { SetThreadToken(NULL, *hUser); if (*hUser) { CloseHandle (*hUser); *hUser = NULL; } return TRUE; } //************************************************************* // // GuidToString, StringToGuid, ValidateGuid, CompareGuid() // // Purpose: Guid utility functions // //************************************************************* // // Length in chars of string form of guid {44cffeec-79d0-11d2-a89d-00c04fbbcfa2} // #define GUID_LENGTH 38 void GuidToString( GUID *pGuid, TCHAR * szValue ) { wsprintf( szValue, TEXT("{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"), pGuid->Data1, pGuid->Data2, pGuid->Data3, pGuid->Data4[0], pGuid->Data4[1], pGuid->Data4[2], pGuid->Data4[3], pGuid->Data4[4], pGuid->Data4[5], pGuid->Data4[6], pGuid->Data4[7] ); } void StringToGuid( TCHAR * szValue, GUID * pGuid ) { WCHAR wc; INT i; // // If the first character is a '{', skip it // if ( szValue[0] == L'{' ) szValue++; // // Since szValue may be used again, no permanent modification to // it is be made. // wc = szValue[8]; szValue[8] = 0; pGuid->Data1 = wcstoul( &szValue[0], 0, 16 ); szValue[8] = wc; wc = szValue[13]; szValue[13] = 0; pGuid->Data2 = (USHORT)wcstoul( &szValue[9], 0, 16 ); szValue[13] = wc; wc = szValue[18]; szValue[18] = 0; pGuid->Data3 = (USHORT)wcstoul( &szValue[14], 0, 16 ); szValue[18] = wc; wc = szValue[21]; szValue[21] = 0; pGuid->Data4[0] = (unsigned char)wcstoul( &szValue[19], 0, 16 ); szValue[21] = wc; wc = szValue[23]; szValue[23] = 0; pGuid->Data4[1] = (unsigned char)wcstoul( &szValue[21], 0, 16 ); szValue[23] = wc; for ( i = 0; i < 6; i++ ) { wc = szValue[26+i*2]; szValue[26+i*2] = 0; pGuid->Data4[2+i] = (unsigned char)wcstoul( &szValue[24+i*2], 0, 16 ); szValue[26+i*2] = wc; } } BOOL ValidateGuid( TCHAR *szValue ) { // // Check if szValue is of form {19e02dd6-79d2-11d2-a89d-00c04fbbcfa2} // if ( lstrlen(szValue) < GUID_LENGTH ) return FALSE; if ( szValue[0] != TEXT('{') || szValue[9] != TEXT('-') || szValue[14] != TEXT('-') || szValue[19] != TEXT('-') || szValue[24] != TEXT('-') || szValue[37] != TEXT('}') ) { return FALSE; } return TRUE; } INT CompareGuid( GUID * pGuid1, GUID * pGuid2 ) { INT i; if ( pGuid1->Data1 != pGuid2->Data1 ) return ( pGuid1->Data1 < pGuid2->Data1 ? -1 : 1 ); if ( pGuid1->Data2 != pGuid2->Data2 ) return ( pGuid1->Data2 < pGuid2->Data2 ? -1 : 1 ); if ( pGuid1->Data3 != pGuid2->Data3 ) return ( pGuid1->Data3 < pGuid2->Data3 ? -1 : 1 ); for ( i = 0; i < 8; i++ ) { if ( pGuid1->Data4[i] != pGuid2->Data4[i] ) return ( pGuid1->Data4[i] < pGuid2->Data4[i] ? -1 : 1 ); } return 0; }