//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1993 - 1993. // // File: ccompapi.cxx // // Contents: common compobj API Worker routines used by com, stg, scm etc // // Classes: // // Functions: // // History: 31-Dec-93 ErikGav Chicago port // //---------------------------------------------------------------------------- #include #include #include #include NAME_SEG(CompApi) ASSERTDATA static const BYTE GuidMap[] = { 3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-', 8, 9, '-', 10, 11, 12, 13, 14, 15}; static const WCHAR wszDigits[] = L"0123456789ABCDEF"; LPVOID WINAPI PrivHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); BOOL WINAPI PrivHeapFree (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem); HANDLE g_hHeap = 0; HEAP_ALLOC_ROUTINE *pfnHeapAlloc = PrivHeapAlloc; HEAP_FREE_ROUTINE *pfnHeapFree = PrivHeapFree; //+------------------------------------------------------------------------- // // Function: PrivHeapAlloc (internal) // // Synopsis: Allocate memory from the heap. // // Notes: This function handles the first call to PrivMemAlloc. // This function changes pfnHeapAlloc so that subsequent calls // to PrivMemAlloc will go directly to HeapAlloc. // //-------------------------------------------------------------------------- LPVOID WINAPI PrivHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) { // Fault in g_hHeap if it's not initialized already via MallocInitialize if (g_hHeap == NULL) { g_hHeap = GetProcessHeap(); if (g_hHeap == NULL) { return NULL; } } pfnHeapFree = HeapFree; pfnHeapAlloc = HeapAlloc; return HeapAlloc(g_hHeap, dwFlags, dwBytes); } //+------------------------------------------------------------------------- // // Function: PrivHeapFree (internal) // // Synopsis: Free memory from the heap. // // Notes: lpMem should always be zero. We assume that memory // freed via PrivMemFree has been allocated via PrivMemAlloc. // The first call to PrivMemAlloc changes pfnHeapFree. // Subsequent calls to PrivMemFree go directly to HeapFree. // Therefore PrivHeapFree should never be called with a // non-zero lpMem. // //-------------------------------------------------------------------------- BOOL WINAPI PrivHeapFree (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) { Win4Assert(lpMem == 0 && "PrivMemFree requires PrivMemAlloc."); return FALSE; } //+------------------------------------------------------------------------- // // Function: wStringFromUUID (internal) // // Synopsis: converts UUID into xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // // Arguments: [rguid] - the guid to convert // [lpszy] - buffer to hold the results // // Returns: Number of characters copied to the buffer. // //-------------------------------------------------------------------------- INTERNAL wStringFromUUID(REFGUID rguid, LPWSTR lpsz) { int i; LPWSTR p = lpsz; const BYTE * pBytes = (const BYTE *) &rguid; for (i = 0; i < sizeof(GuidMap); i++) { if (GuidMap[i] == '-') { *p++ = L'-'; } else { *p++ = wszDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ]; *p++ = wszDigits[ (pBytes[GuidMap[i]] & 0x0F) ]; } } *p = L'\0'; return S_OK; } //+------------------------------------------------------------------------- // // Function: HexStringToDword (private) // // Synopsis: scan lpsz for a number of hex digits (at most 8); update lpsz // return value in Value; check for chDelim; // // Arguments: [lpsz] - the hex string to convert // [Value] - the returned value // [cDigits] - count of digits // // Returns: TRUE for success // //-------------------------------------------------------------------------- static 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; else return TRUE; } //+------------------------------------------------------------------------- // // Function: wUUIDFromString (internal) // // Synopsis: Parse UUID such as 00000000-0000-0000-0000-000000000000 // // Arguments: [lpsz] - Supplies the UUID string to convert // [pguid] - Returns the GUID. // // Returns: TRUE if successful // //-------------------------------------------------------------------------- INTERNAL_(BOOL) wUUIDFromString(LPCWSTR lpsz, LPGUID pguid) { DWORD dw; 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, 0)) return FALSE; pguid->Data4[7] = (BYTE)dw; return TRUE; } //+------------------------------------------------------------------------- // // Function: wGUIDFromString (internal) // // Synopsis: Parse GUID such as {00000000-0000-0000-0000-000000000000} // // Arguments: [lpsz] - the guid string to convert // [pguid] - guid to return // // Returns: TRUE if successful // // CODEWORK: these are common with com\class\compapi.cxx .. // //-------------------------------------------------------------------------- INTERNAL_(BOOL) wGUIDFromString(LPCWSTR lpsz, LPGUID pguid) { DWORD dw; if (*lpsz++ != '{' ) return FALSE; if (wUUIDFromString(lpsz, pguid) != TRUE) return FALSE; lpsz +=36; if (*lpsz++ != '}' ) return FALSE; if (*lpsz != '\0') // check for zero terminated string - test bug #18307 { return FALSE; } return TRUE; } //+------------------------------------------------------------------------- // // Function: wStringFromGUID2 (internal) // // Synopsis: converts GUID into {...} form without leading identifier; // // Arguments: [rguid] - the guid to convert // [lpszy] - buffer to hold the results // [cbMax] - sizeof the buffer // // Returns: amount of data copied to lpsz if successful // 0 if buffer too small. // //-------------------------------------------------------------------------- INTERNAL_(int) wStringFromGUID2(REFGUID rguid, LPWSTR lpsz, int cbMax) { int i; LPWSTR p = lpsz; if (cbMax < GUIDSTR_MAX) return 0; *p++ = L'{'; wStringFromUUID(rguid, p); p += 36; *p++ = L'}'; *p = L'\0'; return GUIDSTR_MAX; } static const CHAR szDigits[] = "0123456789ABCDEF"; //+------------------------------------------------------------------------- // // Function: wStringFromGUID2A (internal) // // Synopsis: Ansi version of wStringFromGUID2 (for Win95 Optimizations) // // Arguments: [rguid] - the guid to convert // [lpszy] - buffer to hold the results // [cbMax] - sizeof the buffer // // Returns: amount of data copied to lpsz if successful // 0 if buffer too small. // //-------------------------------------------------------------------------- INTERNAL_(int) wStringFromGUID2A(REFGUID rguid, LPSTR lpsz, int cbMax) // internal { int i; LPSTR p = lpsz; const BYTE * pBytes = (const BYTE *) &rguid; *p++ = '{'; for (i = 0; i < sizeof(GuidMap); i++) { if (GuidMap[i] == '-') { *p++ = '-'; } else { *p++ = szDigits[ (pBytes[GuidMap[i]] & 0xF0) >> 4 ]; *p++ = szDigits[ (pBytes[GuidMap[i]] & 0x0F) ]; } } *p++ = '}'; *p = '\0'; return GUIDSTR_MAX; } //+--------------------------------------------------------------------------- // // Function: FormatHexNumA // // Synopsis: Given a value, and a count of characters, translate // the value into a hex string. This is the ANSI version // // Arguments: [ulValue] -- Value to convert // [chChars] -- Number of characters to format // [pchStr] -- Pointer to output buffer // // Requires: pwcStr must be valid for chChars // // History: 12-Dec-95 KevinRo Created // // Notes: // //---------------------------------------------------------------------------- void FormatHexNumA( unsigned long ulValue, unsigned long chChars, char *pchStr) { while (chChars--) { pchStr[chChars] = (char) szDigits[ulValue & 0xF]; ulValue = ulValue >> 4; } } //+--------------------------------------------------------------------------- // // Function: FormatHexNumW // // Synopsis: Given a value, and a count of characters, translate // the value into a hex string. This is the WCHAR version // // Arguments: [ulValue] -- Value to convert // [chChars] -- Number of characters to format // [pwcStr] -- Pointer to output buffer // // Requires: pwcStr must be valid for chChars // // History: 12-Dec-95 KevinRo Created // // Notes: // //---------------------------------------------------------------------------- void FormatHexNumW( unsigned long ulValue, unsigned long chChars, WCHAR *pwcStr) { while (chChars--) { pwcStr[chChars] = (char) wszDigits[ulValue & 0xF]; ulValue = ulValue >> 4; } }