//************************************************************* // // Private Profile APIs wrapper to deal with long names // // Microsoft Confidential // Copyright (c) Microsoft Corporation 1997-2000 // All rights reserved // //************************************************************* #include "uenv.h" #define CREATE_FILE_MAX_PATH MAX_PATH #define LONG_LOCAL_PATH_PREFIX TEXT("\\\\?\\") #define LONG_PATH_PREFIX_LEN 8 #define IS_LONG_FILE_NAME(lpFileName) ((lpFileName[0] == TEXT('\\')) && (lpFileName[1] == TEXT('\\')) && (lpFileName[2] == TEXT('?'))) //************************************************************* // ConvertToLongPath() // // Purpose: converts the given absolute path to long path names // // Parameters: // // // Return: // True if successful, False otherwise. GetLastError for more details // // Comments: // //************************************************************* BOOL ConvertToLongPath(LPCTSTR lpFileName, LPTSTR lpLongName) { // // Convert the path to long path.. // if (!IS_LONG_FILE_NAME(lpFileName) && (lstrlen(lpFileName) >= CREATE_FILE_MAX_PATH)) { // // Path is less than MAX_PATH or it is already a long path name // if (IsUNCPath(lpFileName)) { lstrcpy(lpLongName, LONG_UNC_PATH_PREFIX); lstrcat(lpLongName, lpFileName+1); } else { lstrcpy(lpLongName, LONG_LOCAL_PATH_PREFIX); lstrcat(lpLongName, lpFileName); } } else { lstrcpy(lpLongName, lpFileName); } return TRUE; } //************************************************************* // GetIniTmpFileName() // // Purpose: gets a temp file name to copy down the ini file // // Parameters: // // // Return: // True if successful, False otherwise. GetLastError for more details // // Comments: // //************************************************************* BOOL GetIniTmpFileName(LPTSTR szTempFile) { XPtrLF xTmpPath; DWORD dwSizeRequired; szTempFile[0] = TEXT('\0'); xTmpPath = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*MAX_PATH); if (!xTmpPath) { DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't allocate memory for tmpfile path"))); return FALSE; } // // get the temp path // dwSizeRequired = GetTempPath(MAX_PATH, xTmpPath); if (dwSizeRequired == 0) { DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't gettemppath. Error %d"), GetLastError())); return FALSE; } if (dwSizeRequired >= MAX_PATH) { // // retry with a larger buffer // xTmpPath = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*dwSizeRequired); if (!xTmpPath) { DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't allocate memory for tmpfile path(2)"))); return FALSE; } dwSizeRequired = GetTempPath(dwSizeRequired, xTmpPath); if (dwSizeRequired == 0) { DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't gettemppath. Error %d"), GetLastError())); return FALSE; } } // // Now get a temp file in the temp directory // if (!GetTempFileName(xTmpPath, TEXT("ini"), 0, szTempFile)) { DebugMsg((DM_WARNING, TEXT("GetIniTmpFileName: Couldn't gettempfilename. Error - %d"), GetLastError())); return FALSE; } return TRUE; } //************************************************************* // // MyGetPrivateProfileString() // // Purpose: A version of PrivateProfileString that takes long UNC Path // // Parameters: // // // Return: // True if successful, False otherwise. GetLastError for more details // // Comments: // // This returns TRUE or false based on whether it managed to read // successfully. In a case where it fails it will copy the default to // the output string GetLastError for more details //************************************************************* DWORD MyGetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName) { XPtrLF xSrcBuf; TCHAR szTempFile[MAX_PATH+1]; DWORD dwSize; DWORD dwRet=0; // // copy the default string first // lstrcpy(lpReturnedString, lpDefault); // // get the temp file name // if (!GetIniTmpFileName(szTempFile)) { return 0; } xSrcBuf = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(lpFileName)+1+LONG_PATH_PREFIX_LEN)); if (!xSrcBuf) { DebugMsg((DM_WARNING, TEXT("MyGetPrivateProfileString: Couldn't allocate memory for filename"))); return 0; } // // Convert the given path to a long name.. // ConvertToLongPath(lpFileName, xSrcBuf); DebugMsg((DM_VERBOSE, TEXT("MyGetPrivateProfileString: Reading from File <%s>"), xSrcBuf)); // // copy the ini file to the local path // if (!CopyFile(xSrcBuf, szTempFile, FALSE)) { DebugMsg((DM_WARNING, TEXT("MyGetPrivateProfileString: Couldn't copy file to temp file. Error %d"), GetLastError())); return 0; } // // Now call the proper API // dwRet = GetPrivateProfileString(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, szTempFile); // // Delete it once we are done // DeleteFile(szTempFile); DebugMsg((DM_VERBOSE, TEXT("MyGetPrivateProfileString: Read value %s from File <%s>"), lpReturnedString, xSrcBuf)); return dwRet; } //************************************************************* // // MyGetPrivateProfileInt() // // Purpose: A version of PrivateProfileInt that takes long UNC Path // // Parameters: // // // Return: // True if successful, False otherwise. GetLastError for more details // // Comments: // // This returns TRUE or false based on whether it managed to read // successfully. In a case where it fails it will copy the default to // the output string GetLastError for more details //************************************************************* UINT MyGetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName) { XPtrLF xSrcBuf; TCHAR szTempFile[MAX_PATH+1]; DWORD dwSize, dwSizeRequired; UINT uRet=nDefault; if (!GetIniTmpFileName(szTempFile)) { return 0; } xSrcBuf = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(lpFileName)+1+LONG_PATH_PREFIX_LEN)); if (!xSrcBuf) { DebugMsg((DM_WARNING, TEXT("MyGetPrivateProfileString: Couldn't allocate memory for filename"))); return 0; } ConvertToLongPath(lpFileName, xSrcBuf); DebugMsg((DM_VERBOSE, TEXT("MyGetPrivateProfileString: Reading from File <%s>"), xSrcBuf)); if (!CopyFile(xSrcBuf, szTempFile, FALSE)) { DebugMsg((DM_WARNING, TEXT("MyGetPrivateProfileString: Couldn't copy file to temp file. Error %d"), GetLastError())); return 0; } uRet = GetPrivateProfileInt(lpAppName, lpKeyName, nDefault, szTempFile); DeleteFile(szTempFile); DebugMsg((DM_VERBOSE, TEXT("MyGetPrivateProfileString: Read value %d from File <%s>"), uRet, xSrcBuf)); return uRet; } //************************************************************* // // MyWritePrivateProfileString() // // Purpose: A version of PrivateProfileString that takes long UNC Path // // Parameters: // // // Return: // True if successful, False otherwise. GetLastError for more details // // Comments: // // This returns TRUE or false based on whether it managed to read // successfully. In a case where it fails it will copy the default to // the output string GetLastError for more details //************************************************************* DWORD MyWritePrivateProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPTSTR lpString, LPCTSTR lpFileName) { XPtrLF xSrcBuf; TCHAR szTempFile[MAX_PATH+1]; DWORD dwSize, dwSizeRequired, dwRet=0; if (!GetIniTmpFileName(szTempFile)) { return 0; } xSrcBuf = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)*(lstrlen(lpFileName)+1+LONG_PATH_PREFIX_LEN)); if (!xSrcBuf) { DebugMsg((DM_WARNING, TEXT("MyWritePrivateProfileString: Couldn't allocate memory for filename"))); return 0; } ConvertToLongPath(lpFileName, xSrcBuf); DebugMsg((DM_VERBOSE, TEXT("MyWritePrivateProfileString: Writing to File <%s>"), xSrcBuf)); if (!CopyFile(xSrcBuf, szTempFile, FALSE)) { if (GetLastError() != ERROR_FILE_NOT_FOUND) { DebugMsg((DM_WARNING, TEXT("MyWritePrivateProfileString: Couldn't copy file to temp file. Error %d"), GetLastError())); return 0; } } if (!(dwRet = WritePrivateProfileString(lpAppName, lpKeyName, lpString, szTempFile))) { DebugMsg((DM_WARNING, TEXT("MyWritePrivateProfileString: Couldn't Write to temp file. Error %d"), GetLastError())); goto Exit; } if (!CopyFile(szTempFile, xSrcBuf, FALSE)) { DebugMsg((DM_WARNING, TEXT("MyWritePrivateProfileString: Couldn't copy temp ini file to <%s> file. Error %d"), xSrcBuf, GetLastError())); goto Exit; } DeleteFile(szTempFile); return dwRet; Exit: DeleteFile(szTempFile); return 0; }