|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996.
//
// File: actmisc.cxx
//
// Contents: Miscellaneous functions.
//
// Functions:
//
// History:
//
//--------------------------------------------------------------------------
#include "act.hxx"
HRESULT GetMachineName( WCHAR * pwszPath, WCHAR wszMachineName[MAX_COMPUTERNAME_LENGTH+1] #ifdef DFSACTIVATION
,BOOL bDoDfsConversion #endif
) { WCHAR * pwszServerName; BYTE Buffer[sizeof(REMOTE_NAME_INFO)+MAX_PATH*sizeof(WCHAR)]; DWORD BufferSize = sizeof(Buffer); WCHAR Drive[4]; DWORD Status;
//
// Extract the server name from the file's path name.
//
if ( pwszPath[0] != L'\\' || pwszPath[1] != L'\\' ) { lstrcpynW(Drive, pwszPath, 3); Drive[2] = L'\\'; Drive[3] = NULL;
// We must impersonate around the call to GetDriveType as well,
// so that we have the same access to the mapped drive as the
// calling client.
if ( RpcImpersonateClient((RPC_BINDING_HANDLE)0) != ERROR_SUCCESS ) return CO_E_SCM_RPC_FAILURE;
if (GetDriveType(Drive) != DRIVE_REMOTE ) { RpcRevertToSelf(); return S_FALSE; }
Status = WNetGetUniversalName( pwszPath, UNIVERSAL_NAME_INFO_LEVEL, Buffer, &BufferSize );
RpcRevertToSelf();
if ( Status != NO_ERROR ) { return CO_E_BAD_PATH; }
pwszPath = ((UNIVERSAL_NAME_INFO *)Buffer)->lpUniversalName;
if ( ! pwszPath || pwszPath[0] != L'\\' || pwszPath[1] != L'\\' ) { // Must be a local path.
return S_FALSE; } }
#ifdef DFSACTIVATION
WCHAR wszDfsPath[MAX_PATH]; WCHAR * pwszDfsPath = wszDfsPath;
if ( bDoDfsConversion && ghDfs ) { DWORD DfsPathLen;
DfsPathLen = sizeof(wszDfsPath);
for (;;) { Status = DfsFsctl( ghDfs, FSCTL_DFS_GET_SERVER_NAME, (PVOID) &pwszPath[1], lstrlenW(&pwszPath[1]) * sizeof(WCHAR), (PVOID) pwszDfsPath, &DfsPathLen );
if ( Status == STATUS_BUFFER_OVERFLOW ) { ASSERT( pwszDfsPath == wszDfsPath );
pwszDfsPath = (WCHAR *) PrivMemAlloc( DfsPathLen ); if ( ! pwszDfsPath ) return E_OUTOFMEMORY; continue; }
break; }
if ( Status == STATUS_SUCCESS ) pwszPath = pwszDfsPath; } #endif
// Skip the "\\".
LPWSTR pwszTemp = pwszPath + 2;
pwszServerName = wszMachineName;
while ( *pwszTemp != L'\\' ) *pwszServerName++ = *pwszTemp++; *pwszServerName = 0;
#ifdef DFSACTIVATION
if ( pwszDfsPath != wszDfsPath ) PrivMemFree( pwszDfsPath ); #endif
return S_OK; }
HRESULT GetPathForServer( WCHAR * pwszPath, WCHAR wszPathForServer[MAX_PATH+1], WCHAR ** ppwszPathForServer ) { BYTE Buffer[sizeof(REMOTE_NAME_INFO)+MAX_PATH*sizeof(WCHAR)]; WCHAR Drive[4]; DWORD BufferSize = sizeof(Buffer); DWORD PathLength; DWORD Status; UINT uiDriveType;
*ppwszPathForServer = 0;
if ( pwszPath && (lstrlenW(pwszPath) >= 3) && (pwszPath[1] == L':') && (pwszPath[2] == L'\\') ) { lstrcpynW(Drive, pwszPath, 3); Drive[2] = L'\\'; Drive[3] = NULL;
// We must impersonate around the call to GetDriveType as well,
// so that we have the same access to the mapped drive as the
// calling client.
if ( RpcImpersonateClient((RPC_BINDING_HANDLE)0) != ERROR_SUCCESS ) return CO_E_SCM_RPC_FAILURE;
uiDriveType = GetDriveType( Drive );
RpcRevertToSelf();
switch ( uiDriveType ) { case 0 : // Drive type can not be determined
case 1 : // The root directory does not exist
case DRIVE_CDROM : case DRIVE_RAMDISK : case DRIVE_REMOVABLE : //
// We can't convert these to file names that the server will be
// able to access.
//
return CO_E_BAD_PATH;
case DRIVE_FIXED : if ( !gpMachineName || !gpMachineName->NetBiosName()) { return E_OUTOFMEMORY; } wszPathForServer[0] = wszPathForServer[1] = L'\\'; lstrcpyW( &wszPathForServer[2], gpMachineName->NetBiosName() ); PathLength = lstrlenW( wszPathForServer ); wszPathForServer[PathLength] = L'\\'; wszPathForServer[PathLength+1] = pwszPath[0]; wszPathForServer[PathLength+2] = L'$'; wszPathForServer[PathLength+3] = L'\\'; lstrcpyW( &wszPathForServer[PathLength+4], &pwszPath[3] ); *ppwszPathForServer = wszPathForServer; break;
case DRIVE_REMOTE : if ( RpcImpersonateClient((RPC_BINDING_HANDLE)0) != ERROR_SUCCESS ) return CO_E_SCM_RPC_FAILURE;
Status = WNetGetUniversalName( pwszPath, UNIVERSAL_NAME_INFO_LEVEL, Buffer, &BufferSize );
RpcRevertToSelf();
if ( Status != NO_ERROR ) { return CO_E_BAD_PATH; }
ASSERT( ((UNIVERSAL_NAME_INFO *)Buffer)->lpUniversalName );
lstrcpyW( wszPathForServer, ((UNIVERSAL_NAME_INFO *)Buffer)->lpUniversalName );
*ppwszPathForServer = wszPathForServer;
ASSERT( wszPathForServer[0] == L'\\' && wszPathForServer[1] == L'\\' ); break; } } else { *ppwszPathForServer = pwszPath; }
return S_OK; }
//
// Finds an exe name by looking for the first .exe sub string which
// is followed by any of the given delimiter chars or a null.
//
BOOL FindExeComponent( IN WCHAR * pwszString, IN WCHAR * pwszDelimiters, OUT WCHAR ** ppwszStart, OUT WCHAR ** ppwszEnd ) { WCHAR * pwszLast; WCHAR * pwszSearch; WCHAR wszStr[4]; DWORD Delimiters;
Delimiters = lstrlenW( pwszDelimiters ) + 1;
pwszSearch = pwszString; pwszLast = pwszSearch + lstrlenW( pwszSearch );
for ( ; pwszSearch <= (pwszLast - 4); pwszSearch++ ) { if ( pwszSearch[0] != L'.' ) continue;
for ( DWORD n = 0; n < Delimiters; n++ ) { if ( pwszDelimiters[n] == pwszSearch[4] ) { // Note that there is no lstrnicmpW, so we use memcpy/lstrcmpiW.
memcpy( wszStr, &pwszSearch[1], 3 * sizeof(WCHAR) ); wszStr[3] = 0;
if ( lstrcmpiW( wszStr, L"exe" ) == 0 ) goto FoundExe; } } }
FoundExe:
if ( pwszSearch > (pwszLast - 4) ) return FALSE;
*ppwszEnd = &pwszSearch[4];
for ( ; pwszSearch != pwszString && pwszSearch[-1] != L'\\'; pwszSearch-- ) ;
*ppwszStart = pwszSearch;
return TRUE; }
//+-------------------------------------------------------------------------
//
// Function: HexStringToDword
//
// Synopsis: Convert a character string hex digits to a DWORD
//
// Arguments: [lpsz] - string to convert
// [Value] - where to put the value
// [cDigits] - number of digits expected
// [chDelim] - delimiter for end of string
//
// Returns: TRUE - string converted to a DWORD
// FALSE - string could not be converted
//
// Algorithm: For each digit in the string, shift the value and
// add the value of the digit to the output value. When
// all the digits are processed, if a delimiter is
// provided, make sure the last character is the delimiter.
//
// History: 22-Apr-93 Ricksa Created
//
// Notes: Lifted from CairOLE sources so that SCM will have no
// dependency on compobj.dll.
//
//--------------------------------------------------------------------------
BOOL HexStringToDword( LPCWSTR FAR& lpsz, DWORD FAR& Value, int cDigits, WCHAR chDelim) { int Count;
Value = 0;
for (Count = 0; Count < cDigits; Count++, lpsz++) { if (*lpsz >= '0' && *lpsz <= '9') { Value = (Value << 4) + *lpsz - '0'; } else if (*lpsz >= 'A' && *lpsz <= 'F') { Value = (Value << 4) + *lpsz - 'A' + 10; } else if (*lpsz >= 'a' && *lpsz <= 'f') { Value = (Value << 4) + *lpsz - 'a' + 10; } else { return FALSE; } }
if (chDelim != 0) { return *lpsz++ == chDelim; }
return TRUE; }
//+-------------------------------------------------------------------------
//
// Function: GUIDFromString
//
// Synopsis: Convert a string in Registry to a GUID.
//
// Arguments: [lpsz] - string from registry
// [pguid] - where to put the guid.
//
// Returns: TRUE - GUID conversion successful
// FALSE - GUID conversion failed.
//
// Algorithm: Convert each part of the GUID string to the
// appropriate structure member in the guid using
// HexStringToDword. If all conversions work return
// TRUE.
//
// History: 22-Apr-93 Ricksa Created
//
// Notes: Lifted from CairOLE sources so that SCM will have no
// dependency on compobj.dll.
//
//--------------------------------------------------------------------------
BOOL GUIDFromString(LPCWSTR lpsz, LPGUID pguid) { DWORD dw;
if (*lpsz++ != '{') { return FALSE; }
if (!HexStringToDword(lpsz, pguid->Data1, sizeof(DWORD)*2, '-')) { return FALSE; }
if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-')) { return FALSE; }
pguid->Data2 = (WORD)dw;
if (!HexStringToDword(lpsz, dw, sizeof(WORD)*2, '-')) { return FALSE; }
pguid->Data3 = (WORD)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0)) { return FALSE; }
pguid->Data4[0] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, '-')) { return FALSE; }
pguid->Data4[1] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0)) { return FALSE; }
pguid->Data4[2] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0)) { return FALSE; }
pguid->Data4[3] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0)) { return FALSE; }
pguid->Data4[4] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0)) { return FALSE; }
pguid->Data4[5] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, 0)) { return FALSE; }
pguid->Data4[6] = (BYTE)dw;
if (!HexStringToDword(lpsz, dw, sizeof(BYTE)*2, /*(*/ '}')) { return FALSE; }
pguid->Data4[7] = (BYTE)dw;
return TRUE; }
|