8 typedef struct tagHEAP_STRING_POOLA
11 struct tagHEAP_STRING_POOLA* next;
12 } HEAP_STRING_POOLA, *PHEAP_STRING_POOLA;
14 typedef struct tagHEAP_STRING_POOLW
17 struct tagHEAP_STRING_POOLW* next;
18 } HEAP_STRING_POOLW, *PHEAP_STRING_POOLW;
20 PHEAP_STRING_POOLA heap_string_Apool = NULL;
22 PHEAP_STRING_POOLW heap_string_Wpool = NULL;
24 HANDLE hProcessHeap = NULL;
27 HEAP_alloc ( DWORD len )
29 return RtlAllocateHeap ( hProcessHeap, 0, len );
33 HEAP_free ( LPVOID memory )
35 RtlFreeHeap ( hProcessHeap, 0, memory );
39 HEAP_strdupW ( LPCWSTR src, DWORD len )
46 dst = HEAP_alloc ( (len+1) * sizeof(WCHAR) );
49 memcpy ( dst, src, (len+1)*sizeof(WCHAR) );
54 HEAP_strcpyWtoA ( LPSTR lpszA, LPCWSTR lpszW, DWORD len )
57 RtlUnicodeToMultiByteN ( lpszA, len, NULL, (LPWSTR)lpszW, len*sizeof(WCHAR) );
63 HEAP_strcpyAtoW ( LPWSTR lpszW, LPCSTR lpszA, DWORD len )
66 RtlMultiByteToUnicodeN ( lpszW, len*sizeof(WCHAR), NULL, (LPSTR)lpszA, len );
72 HEAP_strdupWtoA ( LPSTR* ppszA, LPCWSTR lpszW, DWORD len )
77 return STATUS_SUCCESS;
79 *ppszA = HEAP_alloc ( len + 1 );
82 return STATUS_NO_MEMORY;
84 return HEAP_strcpyWtoA ( *ppszA, lpszW, len );
88 HEAP_strdupAtoW ( LPWSTR* ppszW, LPCSTR lpszA, UINT* NewLen )
95 return STATUS_SUCCESS;
97 len = lstrlenA ( lpszA );
99 *ppszW = HEAP_alloc ( (len+1) * sizeof(WCHAR) );
102 return STATUS_NO_MEMORY;
104 if ( NewLen ) *NewLen = (UINT)len;
106 return HEAP_strcpyAtoW ( *ppszW, lpszA, len );
109 char* heap_string_poolA ( const wchar_t* pstrW, DWORD length )
111 PHEAP_STRING_POOLA pPoolEntry = heap_string_Apool;
113 HEAP_strdupWtoA ( &pstrA, pstrW, length );
118 if ( !strcmp ( pPoolEntry->data, pstrA ) )
121 return pPoolEntry->data;
123 pPoolEntry = pPoolEntry->next;
125 pPoolEntry = (PHEAP_STRING_POOLA)HEAP_alloc ( sizeof(HEAP_STRING_POOLA) );
126 pPoolEntry->data = pstrA;
128 // IMHO, synchronization is *not* needed here. This data is process-
129 // local, so the only possible contention is among threads. If a
130 // conflict does occur, the only problem will be a small memory
131 // leak that gets cleared up when the heap is destroyed by the
133 pPoolEntry->next = heap_string_Apool;
134 heap_string_Apool = pPoolEntry;
135 return pPoolEntry->data;
138 wchar_t* heap_string_poolW ( const wchar_t* pstrWSrc, DWORD length )
140 PHEAP_STRING_POOLW pPoolEntry = heap_string_Wpool;
141 wchar_t* pstrW = NULL;
142 pstrW = HEAP_strdupW ( (LPWSTR)pstrWSrc, length );
147 if ( !wcscmp (pPoolEntry->data, pstrW ) )
150 return pPoolEntry->data;
152 pPoolEntry = pPoolEntry->next;
154 pPoolEntry = (PHEAP_STRING_POOLW)HEAP_alloc ( sizeof(HEAP_STRING_POOLW) );
155 pPoolEntry->data = pstrW;
157 // IMHO, synchronization is *not* needed here. This data is process-
158 // local, so the only possible contention is among threads. If a
159 // conflict does occur, the only problem will be a small memory
160 // leak that gets cleared up when the heap is destroyed by the
162 pPoolEntry->next = heap_string_Wpool;
163 heap_string_Wpool = pPoolEntry;
164 return pPoolEntry->data;