Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
#include "cstore.hxx"
HRESULT GetAppmgmtIniFilePath( PSID pSid, LPWSTR* ppwszPath ) { UNICODE_STRING SidString; PTOKEN_USER pTokenUser; WCHAR wszPath[MAX_PATH]; WCHAR * pwszSystemDir; DWORD AllocLength; DWORD Length; DWORD Size; DWORD Status; BOOL bStatus;
Status = ERROR_SUCCESS; *ppwszPath = 0;
pwszSystemDir = wszPath; AllocLength = sizeof(wszPath) / sizeof(WCHAR);
for (;;) { Length = GetSystemDirectory( pwszSystemDir, AllocLength );
if ( 0 == Length ) return HRESULT_FROM_WIN32(GetLastError());
if ( Length >= AllocLength ) { AllocLength = Length + 1; //
// No check for failure of alloca since it throws an
// exception on failure
//
pwszSystemDir = (WCHAR *) alloca( AllocLength * sizeof(WCHAR) );
continue; }
break; }
if ( pSid ) { if ( ERROR_SUCCESS == Status ) { Status = RtlConvertSidToUnicodeString( &SidString, pSid, TRUE ); }
if ( Status != ERROR_SUCCESS ) return HRESULT_FROM_WIN32(Status); } else { RtlInitUnicodeString( &SidString, L"MACHINE" ); }
// System dir + \appmgmt\ + Sid \ + inifilename \ + null
*ppwszPath = new WCHAR[Length + 11 + (SidString.Length / 2) + (sizeof(APPMGMT_INI_FILENAME) / sizeof(WCHAR))];
if ( *ppwszPath ) { lstrcpy( *ppwszPath, pwszSystemDir ); if ( pwszSystemDir[lstrlen(pwszSystemDir)-1] != L'\\' ) lstrcat( *ppwszPath, L"\\" ); lstrcat( *ppwszPath, L"appmgmt\\" ); lstrcat( *ppwszPath, SidString.Buffer ); lstrcat( *ppwszPath, APPMGMT_INI_FILENAME ); } else { Status = ERROR_OUTOFMEMORY; }
if ( pSid ) RtlFreeUnicodeString( &SidString );
return HRESULT_FROM_WIN32(Status); }
HRESULT ReadClassStorePath(PSID pSid, LPWSTR* ppwszClassStorePath) { HRESULT hr; LPWSTR wszIniFilePath;
hr = GetAppmgmtIniFilePath( pSid, &wszIniFilePath);
if (FAILED(hr)) { return hr; }
DWORD nBufferSize; DWORD nCharsReceived; LPWSTR wszResult;
nBufferSize = DEFAULT_CSPATH_LENGTH; wszResult = NULL;
//
// The GetPrivateProfileString function is so horribly designed
// that we have to write this disgusting code below to deal with it
//
for (DWORD dwRetry = 0; dwRetry < 7; dwRetry++) { WCHAR DefaultBuffer = L'\0';
wszResult = new WCHAR [nBufferSize];
if (!wszResult) { hr = E_OUTOFMEMORY; break; }
//
// It turns out that this api has other issues as well -- if the file
// doesn't exist it doesn't even return an error that would
// make sense (like 0) -- instead, I've seen it return 8!
// To get around this interesting behavior, I'll set the first
// character of the string to L'\0' before calling the api -- this means that
// subsequent code will treat the failure as if we read a
// zero length class store path from the file, which is the
// desired behavior.
//
*wszResult = L'\0';
nCharsReceived = GetPrivateProfileString( APPMGMT_INI_CSTORE_SECTIONNAME, APPMGMT_INI_CSPATH_KEYNAME, &DefaultBuffer, wszResult, nBufferSize, wszIniFilePath);
//
// If nothing is written, then there's no point in going forward
// since this api returns the number of characters we need to write
//
if (!nCharsReceived) { hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); break; }
if (nCharsReceived != (nBufferSize - 1)) { break; }
//
// Double the size of the allocation
//
nBufferSize *= 2;
//
// Free the previous allocation
//
delete [] wszResult;
wszResult = NULL; }
if (wszResult && nCharsReceived) { LPWSTR wszAllocatedCSPathForCaller;
*ppwszClassStorePath = new WCHAR[nCharsReceived + 1];
if (*ppwszClassStorePath) { wcscpy(*ppwszClassStorePath, wszResult); } else { hr = E_OUTOFMEMORY; } }
delete [] wszResult;
delete [] wszIniFilePath;
return hr; }
|