Leaked source code of windows server 2003
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.

656 lines
15 KiB

  1. /*++
  2. Copyright (c) 1996, 1997 Microsoft Corporation
  3. Module Name:
  4. misc.cpp
  5. Abstract:
  6. Functionality in this module:
  7. GetCurrentUser allocating wrapper
  8. RegQueryValueEx allocating wrapper
  9. Rule free logic
  10. pulling the file description from file
  11. Author:
  12. Matt Thomlinson (mattt) 22-Oct-96
  13. Scott Field (sfield) 01-Jan-97
  14. --*/
  15. #include <pch.cpp>
  16. #pragma hdrstop
  17. extern DISPIF_CALLBACKS g_sCallbacks;
  18. //
  19. // Registry Setable Globals, and handlign goo
  20. //
  21. // Must access key via api's
  22. static HKEY g_hProtectedStorageKey = NULL;
  23. static HANDLE g_hProtectedStorageChangeEvent = NULL;
  24. static CRITICAL_SECTION g_csGlobals;
  25. static BOOL g_fcsGlobalsInitialized = FALSE;
  26. // supply a new, delete operator
  27. void * __cdecl operator new(size_t cb)
  28. {
  29. return SSAlloc( cb );
  30. }
  31. void __cdecl operator delete(void * pv)
  32. {
  33. SSFree( pv );
  34. }
  35. BOOL FGetCurrentUser(
  36. PST_PROVIDER_HANDLE* phPSTProv,
  37. LPWSTR* ppszUser,
  38. PST_KEY Key)
  39. {
  40. BOOL fRet = FALSE;
  41. if (Key == PST_KEY_LOCAL_MACHINE)
  42. {
  43. *ppszUser = (LPWSTR)SSAlloc(sizeof(WSZ_LOCAL_MACHINE));
  44. if( *ppszUser == NULL )
  45. {
  46. return FALSE;
  47. }
  48. wcscpy(*ppszUser, WSZ_LOCAL_MACHINE);
  49. }
  50. else
  51. {
  52. // get current user
  53. if (!g_sCallbacks.pfnFGetUser(
  54. phPSTProv,
  55. ppszUser))
  56. goto Ret;
  57. }
  58. fRet = TRUE;
  59. Ret:
  60. return fRet;
  61. }
  62. BOOL FStringIsValidItemName(LPCWSTR szTrialString)
  63. {
  64. // local define
  65. #define WCH_INVALID_CHAR1 L'\\'
  66. while( *szTrialString &&
  67. (*szTrialString != WCH_INVALID_CHAR1) )
  68. szTrialString++;
  69. // valid=TRUE if we're at the end of the string
  70. return (*szTrialString == L'\0');
  71. }
  72. // get registry wrapper
  73. DWORD RegGetValue(HKEY hItemKey,
  74. LPWSTR szItem,
  75. PBYTE* ppb,
  76. DWORD* pcb)
  77. {
  78. // local define
  79. #define FASTBUFSIZE 64
  80. /*
  81. FASTBUFSIZE from purely empirical testing (2 tpstorec.exe, 1 perform.exe)
  82. bytes num requests
  83. 16 1437
  84. 18 22
  85. 20 928
  86. 22 18
  87. 24 2
  88. 32 9
  89. 40 106
  90. 42 700
  91. 48 500
  92. 56 928
  93. 64 718
  94. ->
  95. 72 100
  96. 256 500
  97. set cache size at 64. (mattt, 2/3/97)
  98. */
  99. DWORD dwRet;
  100. DWORD dwType;
  101. BYTE rgbFastBuf[FASTBUFSIZE]; // try using a static buffer
  102. BOOL fAllocated = FALSE;
  103. *pcb = FASTBUFSIZE;
  104. dwRet =
  105. RegQueryValueExU(
  106. hItemKey,
  107. szItem,
  108. 0,
  109. &dwType,
  110. rgbFastBuf,
  111. pcb);
  112. if (dwRet == ERROR_SUCCESS)
  113. {
  114. // fastbuf was large enough
  115. *ppb = (PBYTE)SSAlloc(*pcb);
  116. if(*ppb == NULL)
  117. {
  118. dwRet = (DWORD)PST_E_FAIL;
  119. goto Ret;
  120. }
  121. CopyMemory(*ppb, rgbFastBuf, *pcb);
  122. }
  123. else if (dwRet == ERROR_MORE_DATA)
  124. {
  125. // didn't fit into fastbuf -- alloc exact size, query
  126. *ppb = (PBYTE)SSAlloc(*pcb);
  127. if(*ppb == NULL)
  128. {
  129. dwRet = (DWORD)PST_E_FAIL;
  130. goto Ret;
  131. }
  132. fAllocated = TRUE;
  133. if (ERROR_SUCCESS != (dwRet =
  134. RegQueryValueExU(
  135. hItemKey,
  136. szItem,
  137. 0,
  138. &dwType,
  139. *ppb,
  140. pcb)) )
  141. goto Ret;
  142. }
  143. else
  144. goto Ret;
  145. dwRet = PST_E_OK;
  146. Ret:
  147. if( dwRet != PST_E_OK && fAllocated ) {
  148. SSFree( *ppb );
  149. *ppb = NULL;
  150. }
  151. return dwRet;
  152. }
  153. // get registry wrapper
  154. DWORD RegGetStringValue(
  155. HKEY hItemKey,
  156. LPWSTR szItem,
  157. PBYTE* ppb,
  158. DWORD* pcb)
  159. {
  160. DWORD dwRet;
  161. DWORD dwType;
  162. BYTE rgbFastBuf[FASTBUFSIZE]; // try using a static buffer
  163. BOOL fAllocated = FALSE;
  164. *pcb = FASTBUFSIZE;
  165. dwRet =
  166. RegQueryValueExU(
  167. hItemKey,
  168. szItem,
  169. 0,
  170. &dwType,
  171. rgbFastBuf,
  172. pcb);
  173. if (dwRet == ERROR_SUCCESS)
  174. {
  175. // fastbuf was large enough
  176. *ppb = (PBYTE)SSAlloc(*pcb);
  177. if(*ppb == NULL)
  178. {
  179. dwRet = (DWORD)PST_E_FAIL;
  180. goto Ret;
  181. }
  182. CopyMemory(*ppb, rgbFastBuf, *pcb);
  183. }
  184. else if (dwRet == ERROR_MORE_DATA)
  185. {
  186. // didn't fit into fastbuf -- alloc exact size, query
  187. *ppb = (PBYTE)SSAlloc(*pcb);
  188. if(*ppb == NULL)
  189. {
  190. dwRet = (DWORD)PST_E_FAIL;
  191. goto Ret;
  192. }
  193. fAllocated = TRUE;
  194. if (ERROR_SUCCESS != (dwRet =
  195. RegQueryValueExU(
  196. hItemKey,
  197. szItem,
  198. 0,
  199. &dwType,
  200. *ppb,
  201. pcb)) )
  202. goto Ret;
  203. }
  204. else
  205. goto Ret;
  206. // Make sure that the data type is a zero-terminated one.
  207. if((dwType != REG_SZ) &&
  208. (dwType != REG_MULTI_SZ) &&
  209. (dwType != REG_EXPAND_SZ))
  210. {
  211. dwRet = (DWORD)PST_E_INVALID_STRING;
  212. goto Ret;
  213. }
  214. dwRet = PST_E_OK;
  215. Ret:
  216. if( dwRet != PST_E_OK && fAllocated ) {
  217. SSFree( *ppb );
  218. *ppb = NULL;
  219. }
  220. return dwRet;
  221. }
  222. #if 0
  223. void FreeRuleset(
  224. PST_ACCESSRULESET *psRules)
  225. {
  226. PST_ACCESSCLAUSE* pClause;
  227. if (psRules == NULL)
  228. return;
  229. for (DWORD cRule=0; cRule<psRules->cRules; cRule++)
  230. {
  231. // for each Rule in Ruleset, walk all clauses and free assoc pb
  232. for (DWORD cClause=0; cClause<psRules->rgRules[cRule].cClauses; cClause++)
  233. {
  234. pClause = &psRules->rgRules[cRule].rgClauses[cClause];
  235. if (NULL != pClause->pbClauseData)
  236. SSFree(pClause->pbClauseData);
  237. }
  238. // now free rgClause
  239. SSFree(psRules->rgRules[cRule].rgClauses);
  240. }
  241. // now free rgRules
  242. SSFree(psRules->rgRules);
  243. }
  244. #endif
  245. BOOL
  246. GetFileDescription(
  247. LPCWSTR szFile,
  248. LPWSTR *FileDescription
  249. )
  250. /*++
  251. Routine Description:
  252. This function obtains the localized version resource, file description
  253. string from a specified file. The input and output parameters are
  254. both Unicode, and as a result, this requires some "thunking" magic
  255. for Win95.
  256. Arguments:
  257. szFile - Pointer to file name (full path if appropriate) to obtain
  258. the localized file description string from.
  259. FileDescription - Returns a pointer to an allocated, localized file
  260. description string associated with the specified file.
  261. Return Value:
  262. TRUE - success. Caller must free buffer specified by the FileDescription
  263. parameter.
  264. FALSE - error.
  265. Author:
  266. Scott Field (sfield) 02-Jan-97
  267. --*/
  268. {
  269. LPCVOID FileName;
  270. CHAR FileNameA[MAX_PATH];
  271. DWORD dwVerInfoSize;
  272. DWORD dwHandle;
  273. LPVOID VerInfo;
  274. LPVOID lpBuffer;
  275. UINT puLen;
  276. DWORD dwLanguageId;
  277. LPVOID Trans;
  278. LPVOID StringFileInfo;
  279. LPVOID Language;
  280. CHAR StringFileInfoA[] = "\\StringFileInfo\\%04X%04X\\FileDescription";
  281. WCHAR StringFileInfoW[] = L"\\StringFileInfo\\%04X%04X\\FileDescription";
  282. CHAR LanguageA[sizeof(StringFileInfoA)/sizeof(CHAR)];
  283. WCHAR LanguageW[sizeof(StringFileInfoW)/sizeof(WCHAR)];
  284. LANGID LangDefault;
  285. BOOL bSuccess = FALSE;
  286. typedef BOOL (WINAPI GETFILEVERSIONINFOSIZE)(LPCVOID, LPDWORD);
  287. typedef BOOL (WINAPI GETFILEVERSIONINFO)(LPCVOID, DWORD, DWORD, LPVOID);
  288. typedef int (cdecl WSPRINTF)(LPVOID, LPVOID, ...);
  289. typedef BOOL (WINAPI VERQUERYVALUE)(LPVOID, LPVOID, LPVOID *, PUINT);
  290. GETFILEVERSIONINFOSIZE *_GetFileVersionInfoSize;
  291. GETFILEVERSIONINFO *_GetFileVersionInfo;
  292. WSPRINTF *_wsprintf;
  293. VERQUERYVALUE *_VerQueryValue;
  294. static BOOL fLoadedVersionDll = FALSE;
  295. static FARPROC _GetFileVersionInfoSizeW;
  296. static FARPROC _GetFileVersionInfoW;
  297. static FARPROC _VerQueryValueW;
  298. static FARPROC _GetFileVersionInfoSizeA;
  299. static FARPROC _GetFileVersionInfoA;
  300. static FARPROC _VerQueryValueA;
  301. *FileDescription = NULL;
  302. if( !fLoadedVersionDll ) {
  303. HMODULE hVersionDll = LoadLibraryU(L"version.dll");
  304. if( hVersionDll == NULL )
  305. return FALSE;
  306. if(FIsWinNT()) {
  307. _GetFileVersionInfoSizeW = GetProcAddress(hVersionDll, "GetFileVersionInfoSizeW");
  308. if(_GetFileVersionInfoSizeW == NULL)
  309. return FALSE;
  310. _GetFileVersionInfoW = GetProcAddress(hVersionDll, "GetFileVersionInfoW");
  311. if(_GetFileVersionInfoW == NULL)
  312. return FALSE;
  313. _VerQueryValueW = GetProcAddress(hVersionDll, "VerQueryValueW");
  314. if(_VerQueryValueW == NULL)
  315. return FALSE;
  316. } else {
  317. _GetFileVersionInfoSizeA = GetProcAddress(hVersionDll, "GetFileVersionInfoSizeA");
  318. if(_GetFileVersionInfoSizeA == NULL)
  319. return FALSE;
  320. _GetFileVersionInfoA = GetProcAddress(hVersionDll, "GetFileVersionInfoA");
  321. if(_GetFileVersionInfoA == NULL)
  322. return FALSE;
  323. _VerQueryValueA = GetProcAddress(hVersionDll, "VerQueryValueA");
  324. if(_VerQueryValueA == NULL)
  325. return FALSE;
  326. }
  327. fLoadedVersionDll = TRUE;
  328. }
  329. //
  330. // could win95 be any more annoying?
  331. //
  332. if(FIsWinNT()) {
  333. _GetFileVersionInfoSize = (GETFILEVERSIONINFOSIZE*)_GetFileVersionInfoSizeW;
  334. _GetFileVersionInfo = (GETFILEVERSIONINFO*)_GetFileVersionInfoW;
  335. _wsprintf = (WSPRINTF *)wsprintfW;
  336. _VerQueryValue = (VERQUERYVALUE*)_VerQueryValueW;
  337. Trans = L"\\VarFileInfo\\Translation";
  338. StringFileInfo = StringFileInfoW;
  339. Language = LanguageW;
  340. FileName = szFile; // use unicode input
  341. } else {
  342. _GetFileVersionInfoSize = (GETFILEVERSIONINFOSIZE*)_GetFileVersionInfoSizeA;
  343. _GetFileVersionInfo = (GETFILEVERSIONINFO*)_GetFileVersionInfoA;
  344. _wsprintf = (WSPRINTF *)wsprintfA;
  345. _VerQueryValue = (VERQUERYVALUE*)_VerQueryValueA;
  346. Trans = "\\VarFileInfo\\Translation";
  347. StringFileInfo = StringFileInfoA;
  348. Language = LanguageA;
  349. FileName = FileNameA;
  350. // convert unicode input to ANSI
  351. if(WideCharToMultiByte(
  352. CP_ACP,
  353. 0,
  354. szFile,
  355. -1,
  356. (LPSTR)FileName,
  357. MAX_PATH,
  358. NULL,
  359. NULL
  360. ) == 0) {
  361. return FALSE;
  362. }
  363. }
  364. dwVerInfoSize = _GetFileVersionInfoSize(FileName, &dwHandle);
  365. if(dwVerInfoSize == 0)
  366. return FALSE;
  367. VerInfo = SSAlloc(dwVerInfoSize);
  368. if(VerInfo == NULL)
  369. return FALSE;
  370. if(!_GetFileVersionInfo(FileName, dwHandle, dwVerInfoSize, VerInfo))
  371. goto cleanup;
  372. //
  373. // first, try current language
  374. //
  375. LangDefault = GetUserDefaultLangID();
  376. _wsprintf( Language, StringFileInfo, LangDefault, 1200);
  377. if(_VerQueryValue(VerInfo, Language, &lpBuffer, &puLen)) {
  378. goto success;
  379. }
  380. //
  381. // try languages in translation table
  382. //
  383. if(_VerQueryValue(VerInfo, Trans, &lpBuffer, &puLen)) {
  384. DWORD dwTranslationCount = puLen / sizeof(DWORD);
  385. DWORD dwIndexTranslation;
  386. for(dwIndexTranslation = 0 ;
  387. dwIndexTranslation < dwTranslationCount ;
  388. dwIndexTranslation++ ) {
  389. DWORD LangID, CharSetID;
  390. LangID = LOWORD( ((DWORD*)lpBuffer)[dwIndexTranslation] );
  391. CharSetID = HIWORD( ((DWORD*)lpBuffer)[dwIndexTranslation] );
  392. _wsprintf(Language, StringFileInfo, LangID, CharSetID);
  393. if(_VerQueryValue(VerInfo, Language, &lpBuffer, &puLen)) {
  394. goto success;
  395. }
  396. } // for
  397. }
  398. //
  399. // try english, Unicode if we didn't already
  400. //
  401. if(LangDefault != MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)) {
  402. _wsprintf(Language, StringFileInfo,
  403. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  404. 1200);
  405. if(_VerQueryValue(VerInfo, Language, &lpBuffer, &puLen)) {
  406. goto success;
  407. }
  408. }
  409. //
  410. // try english, code page 1252
  411. //
  412. _wsprintf(Language, StringFileInfo,
  413. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  414. 1252);
  415. if(_VerQueryValue(VerInfo, Language, &lpBuffer, &puLen)) {
  416. goto success;
  417. }
  418. //
  419. // try english, code page 0000
  420. //
  421. _wsprintf(Language, StringFileInfo,
  422. MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
  423. 0);
  424. if(_VerQueryValue(VerInfo, Language, &lpBuffer, &puLen)) {
  425. goto success;
  426. }
  427. //
  428. // failed! skip to cleanup
  429. //
  430. goto cleanup;
  431. success:
  432. *FileDescription = (LPWSTR)SSAlloc((puLen + 1) * sizeof(WCHAR));
  433. if(*FileDescription == NULL)
  434. goto cleanup;
  435. bSuccess = TRUE; // assume success
  436. if(FIsWinNT()) {
  437. wcscpy(*FileDescription, (LPWSTR)lpBuffer);
  438. } else {
  439. if(MultiByteToWideChar(
  440. CP_ACP,
  441. 0,
  442. (LPSTR)lpBuffer,
  443. puLen,
  444. *FileDescription,
  445. puLen
  446. ) == 0) {
  447. bSuccess = FALSE;
  448. }
  449. }
  450. cleanup:
  451. if(!bSuccess && *FileDescription) {
  452. SSFree(*FileDescription);
  453. *FileDescription = NULL;
  454. }
  455. SSFree(VerInfo);
  456. return bSuccess;
  457. }
  458. void MyToUpper(LPWSTR szInBuf)
  459. {
  460. DWORD cch = WSZ_BYTECOUNT(szInBuf);
  461. LPWSTR szUpperCase = (LPWSTR)LocalAlloc(LMEM_FIXED, cch);
  462. LCMapStringU(
  463. LOCALE_SYSTEM_DEFAULT,
  464. LCMAP_UPPERCASE,
  465. szInBuf,
  466. -1,
  467. szUpperCase,
  468. cch);
  469. // no growth or shrinkage
  470. SS_ASSERT(wcslen(szInBuf) == wcslen(szUpperCase));
  471. // mash back into passed-in buffer
  472. wcscpy(szInBuf, szUpperCase);
  473. LocalFree(szUpperCase);
  474. }
  475. // cached authentication list
  476. extern CUAList* g_pCUAList;
  477. BOOL
  478. FIsCachedPassword(
  479. LPCWSTR szUser,
  480. LPCWSTR szPassword,
  481. LUID* pluidAuthID
  482. )
  483. {
  484. // see if this MK has been cached
  485. UACACHE_LIST_ITEM li;
  486. if(NULL == g_pCUAList)
  487. {
  488. return FALSE;
  489. }
  490. CreateUACacheListItem(
  491. &li,
  492. szUser,
  493. szPassword,
  494. pluidAuthID
  495. );
  496. // TRUE if cached
  497. return (NULL != g_pCUAList->SearchList(&li));
  498. }