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.

591 lines
13 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. // determines whether trace statements are printed
  4. #define DBL_UNDEFINED ((DWORD)-1)
  5. #define REGKEY_SETUP TEXT("SOFTWARE\\microsoft\\windows\\currentversion\\setup")
  6. #define REGVAL_DBLEVEL TEXT("OC Manager Debug Level")
  7. DWORD gDebugLevel = DBL_UNDEFINED;
  8. //
  9. // OC_MANAGER pointer for debugging/logging
  10. //
  11. extern POC_MANAGER gLastOcManager;
  12. VOID
  13. _DbgOut(
  14. DWORD Severity,
  15. LPCTSTR txt
  16. );
  17. DWORD
  18. GetDebugLevel(
  19. VOID
  20. )
  21. {
  22. DWORD rc;
  23. DWORD err;
  24. DWORD size;
  25. DWORD type;
  26. HKEY hkey;
  27. err = RegOpenKey(HKEY_LOCAL_MACHINE,
  28. REGKEY_SETUP,
  29. &hkey);
  30. if (err != ERROR_SUCCESS)
  31. return 0;
  32. size = sizeof(DWORD);
  33. err = RegQueryValueEx(hkey,
  34. REGVAL_DBLEVEL,
  35. 0,
  36. &type,
  37. (LPBYTE)&rc,
  38. &size);
  39. if (err != ERROR_SUCCESS || type != REG_DWORD)
  40. rc = 0;
  41. RegCloseKey(hkey);
  42. return rc;
  43. }
  44. UINT
  45. _LogError(
  46. IN POC_MANAGER OcManager,
  47. IN OcErrorLevel ErrorLevel,
  48. IN UINT MessageId,
  49. ...
  50. )
  51. {
  52. TCHAR str[5000];
  53. DWORD d;
  54. va_list arglist;
  55. va_start(arglist,MessageId);
  56. d = FormatMessage(
  57. FORMAT_MESSAGE_FROM_HMODULE,
  58. MyModuleHandle,
  59. MessageId,
  60. 0,
  61. str,
  62. sizeof(str)/sizeof(TCHAR),
  63. &arglist
  64. );
  65. va_end(arglist);
  66. if(!d) {
  67. FormatMessage(
  68. FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  69. MyModuleHandle,
  70. MSG_NOT_FOUND,
  71. 0,
  72. str,
  73. sizeof(str)/sizeof(TCHAR),
  74. (va_list *)&MessageId
  75. );
  76. }
  77. if ( OcManager->SetupData.OperationFlags & SETUPOP_BATCH) {
  78. ErrorLevel |= OcErrBatch;
  79. }
  80. return OcLogError(ErrorLevel,str);
  81. }
  82. VOID
  83. _TrcOut(
  84. IN LPCTSTR Format,
  85. ...
  86. )
  87. {
  88. TCHAR str[5000];
  89. va_list arglist;
  90. va_start(arglist,Format);
  91. wvsprintf(str,Format,arglist);
  92. va_end(arglist);
  93. _DbgOut(OcErrTrace,str);
  94. }
  95. VOID
  96. _WrnOut(
  97. LPCTSTR Format,
  98. ...
  99. )
  100. {
  101. TCHAR str[5000];
  102. va_list arglist;
  103. va_start(arglist,Format);
  104. wvsprintf(str,Format,arglist);
  105. va_end(arglist);
  106. _DbgOut(OcErrLevWarning,str);
  107. }
  108. VOID
  109. _ErrOut(
  110. IN LPCTSTR Format,
  111. ...
  112. )
  113. {
  114. TCHAR str[5000];
  115. va_list arglist;
  116. va_start(arglist,Format);
  117. wvsprintf(str,Format,arglist);
  118. va_end(arglist);
  119. _DbgOut(OcErrLevFatal,str);
  120. }
  121. VOID
  122. _DbgOut(
  123. DWORD Severity,
  124. IN LPCTSTR txt
  125. )
  126. {
  127. #if 0
  128. TCHAR str[5000];
  129. va_list arglist;
  130. va_start(arglist,Format);
  131. wvsprintf(str,Format,arglist);
  132. va_end(arglist);
  133. #endif
  134. if (gDebugLevel == DBL_UNDEFINED)
  135. gDebugLevel = GetDebugLevel();
  136. //
  137. // for those people that *dont* want to see this debugger output, they can munge the registry
  138. // to something between 50 and 100 to disable this.
  139. // if we don't log some information on checked builds then we'll miss too many errors the first
  140. // time around
  141. //
  142. if ( (gDebugLevel > 0) && (gDebugLevel < 50) )
  143. return;
  144. if (gLastOcManager) {
  145. gLastOcManager->Callbacks.LogError(Severity, txt);
  146. } else {
  147. OutputDebugString(TEXT("OCMANAGE: "));
  148. OutputDebugString(txt);
  149. OutputDebugString(TEXT("\n"));
  150. }
  151. }
  152. UINT
  153. pOcCreateComponentSpecificMiniIcon(
  154. IN POC_MANAGER OcManager,
  155. IN LONG ComponentId,
  156. IN LPCTSTR Subcomponent,
  157. IN UINT Width,
  158. IN UINT Height,
  159. IN LPCTSTR DllName, OPTIONAL
  160. IN LPCTSTR ResourceId OPTIONAL
  161. )
  162. {
  163. HBITMAP BitmapFromComponent;
  164. HBITMAP NewBitmap;
  165. HBITMAP MaskBitmap;
  166. HBITMAP OldBitmap1,OldBitmap2;
  167. HDC MemDc1,MemDc2;
  168. COLORREF BackgroundColor;
  169. UINT Index;
  170. BITMAP BitmapInfo;
  171. BOOL b;
  172. HMODULE hMod;
  173. Index = DEFAULT_ICON_INDEX;
  174. //
  175. // If a dll name is given then fetch the bitmap from there.
  176. // Otherwise, call down to the component to get the bitmap.
  177. //
  178. BitmapFromComponent = NULL;
  179. if(DllName && ResourceId) {
  180. if(hMod = LoadLibraryEx(DllName,NULL,LOAD_LIBRARY_AS_DATAFILE)) {
  181. BitmapFromComponent = LoadBitmap(hMod,ResourceId);
  182. FreeLibrary(hMod);
  183. }
  184. } else {
  185. //
  186. // first try OC_QUERY_IMAGE_EX for the bitmap
  187. //
  188. BitmapFromComponent = OcInterfaceQueryImageEx(
  189. OcManager,
  190. ComponentId,
  191. Subcomponent,
  192. SubCompInfoSmallIcon,
  193. Width,
  194. Height
  195. );
  196. #ifndef _WIN64
  197. //
  198. // OC_QUERY_IMAGE is broken for 64 bits, so only call this if we
  199. // do not get an image reported for the component on 32 bit targets.
  200. //
  201. if (!BitmapFromComponent) {
  202. BitmapFromComponent = OcInterfaceQueryImage(
  203. OcManager,
  204. ComponentId,
  205. Subcomponent,
  206. SubCompInfoSmallIcon,
  207. Width,
  208. Height
  209. );
  210. }
  211. #else
  212. if (!BitmapFromComponent) {
  213. DbgPrintEx(
  214. DPFLTR_SETUP_ID,
  215. DPFLTR_ERROR_LEVEL,
  216. "No bitmap defined for component. Ensure that component is handling OC_QUERY_IMAGE_EX callback\n");
  217. }
  218. #endif
  219. }
  220. if(!BitmapFromComponent) {
  221. goto c0;
  222. }
  223. //
  224. // Copy the bitmap given to us by the component.
  225. // At the same time, make sure it's the right size.
  226. //
  227. MemDc1 = CreateCompatibleDC(NULL);
  228. if(!MemDc1) {
  229. goto c1;
  230. }
  231. MemDc2 = CreateCompatibleDC(NULL);
  232. if(!MemDc2) {
  233. goto c2;
  234. }
  235. if(!GetObject(BitmapFromComponent,sizeof(BitmapInfo),&BitmapInfo)) {
  236. goto c3;
  237. }
  238. NewBitmap = CreateBitmap(Width,Height,BitmapInfo.bmPlanes,BitmapInfo.bmBitsPixel,NULL);
  239. if(!NewBitmap) {
  240. goto c3;
  241. }
  242. OldBitmap1 = SelectObject(MemDc1,BitmapFromComponent);
  243. if(!OldBitmap1) {
  244. goto c4;
  245. }
  246. OldBitmap2 = SelectObject(MemDc2,NewBitmap);
  247. if(!OldBitmap2) {
  248. goto c5;
  249. }
  250. b = StretchBlt(
  251. MemDc2,
  252. 0,0,
  253. Width,Height,
  254. MemDc1,
  255. 0,0,
  256. BitmapInfo.bmWidth,
  257. BitmapInfo.bmHeight,
  258. SRCCOPY
  259. );
  260. if(!b) {
  261. goto c6;
  262. }
  263. //
  264. // Now make the mask.
  265. //
  266. // The mask bitmap is monochrome. Pixels in the image bitmap that are
  267. // the image bitmap's background color will be white in the mask;
  268. // other pixels in the mask will be black. Assume the upper-left pixel
  269. // of the image bitmap is the background color.
  270. //
  271. BackgroundColor = GetPixel(MemDc2,0,0);
  272. if(BackgroundColor == CLR_INVALID) {
  273. goto c6;
  274. }
  275. MaskBitmap = CreateBitmap(Width,Height,1,1,NULL);
  276. if(!MaskBitmap) {
  277. goto c6;
  278. }
  279. if(!SelectObject(MemDc1,MaskBitmap)) {
  280. goto c7;
  281. }
  282. if(SetBkColor(MemDc2,BackgroundColor) == CLR_INVALID) {
  283. goto c7;
  284. }
  285. if(!BitBlt(MemDc1,0,0,Width,Height,MemDc2,0,0,SRCCOPY)) {
  286. goto c7;
  287. }
  288. //
  289. // Black out all of the transparent parts of the image, in preparation
  290. // for drawing.
  291. //
  292. SetBkColor(MemDc2,RGB(0,0,0));
  293. SetTextColor(MemDc2,RGB(255,255,255));
  294. if(!BitBlt(MemDc2,0,0,Width,Height,MemDc1,0,0,SRCAND)) {
  295. goto c7;
  296. }
  297. //
  298. // Before we call pSetupAddMiniIconToList we have to make sure
  299. // neither bitmap is selected into a DC.
  300. //
  301. SelectObject(MemDc1,OldBitmap1);
  302. SelectObject(MemDc2,OldBitmap2);
  303. Index = pSetupAddMiniIconToList(NewBitmap,MaskBitmap);
  304. if(Index == -1) {
  305. Index = DEFAULT_ICON_INDEX;
  306. }
  307. c7:
  308. DeleteObject(MaskBitmap);
  309. c6:
  310. SelectObject(MemDc2,OldBitmap2);
  311. c5:
  312. SelectObject(MemDc1,OldBitmap1);
  313. c4:
  314. DeleteObject(NewBitmap);
  315. c3:
  316. DeleteDC(MemDc2);
  317. c2:
  318. DeleteDC(MemDc1);
  319. c1:
  320. DeleteObject(BitmapFromComponent);
  321. c0:
  322. return(Index);
  323. }
  324. BOOL
  325. pConvertStringToLongLong(
  326. IN PCTSTR String,
  327. OUT PLONGLONG OutValue
  328. )
  329. /*++
  330. Routine Description:
  331. Arguments:
  332. Return Value:
  333. Remarks:
  334. Hexadecimal numbers are also supported. They must be prefixed by '0x' or '0X', with no
  335. space allowed between the prefix and the number.
  336. --*/
  337. {
  338. LONGLONG Value;
  339. UINT c;
  340. BOOL Neg;
  341. UINT Base;
  342. UINT NextDigitValue;
  343. LONGLONG OverflowCheck;
  344. BOOL b;
  345. if(!String || !OutValue) {
  346. SetLastError(ERROR_INVALID_PARAMETER);
  347. return(FALSE);
  348. }
  349. if(*String == TEXT('-')) {
  350. Neg = TRUE;
  351. String++;
  352. } else {
  353. Neg = FALSE;
  354. if(*String == TEXT('+')) {
  355. String++;
  356. }
  357. }
  358. if((*String == TEXT('0')) &&
  359. ((*(String+1) == TEXT('x')) || (*(String+1) == TEXT('X')))) {
  360. //
  361. // The number is in hexadecimal.
  362. //
  363. Base = 16;
  364. String += 2;
  365. } else {
  366. //
  367. // The number is in decimal.
  368. //
  369. Base = 10;
  370. }
  371. for(OverflowCheck = Value = 0; *String; String++) {
  372. c = (UINT)*String;
  373. if((c >= (UINT)'0') && (c <= (UINT)'9')) {
  374. NextDigitValue = c - (UINT)'0';
  375. } else if(Base == 16) {
  376. if((c >= (UINT)'a') && (c <= (UINT)'f')) {
  377. NextDigitValue = (c - (UINT)'a') + 10;
  378. } else if ((c >= (UINT)'A') && (c <= (UINT)'F')) {
  379. NextDigitValue = (c - (UINT)'A') + 10;
  380. } else {
  381. break;
  382. }
  383. } else {
  384. break;
  385. }
  386. Value *= Base;
  387. Value += NextDigitValue;
  388. //
  389. // Check for overflow. For decimal numbers, we check to see whether the
  390. // new value has overflowed into the sign bit (i.e., is less than the
  391. // previous value. For hexadecimal numbers, we check to make sure we
  392. // haven't gotten more digits than will fit in a DWORD.
  393. //
  394. if(Base == 16) {
  395. if(++OverflowCheck > (sizeof(LONGLONG) * 2)) {
  396. break;
  397. }
  398. } else {
  399. if(Value < OverflowCheck) {
  400. break;
  401. } else {
  402. OverflowCheck = Value;
  403. }
  404. }
  405. }
  406. if(*String) {
  407. SetLastError(ERROR_INVALID_DATA);
  408. return(FALSE);
  409. }
  410. if(Neg) {
  411. Value = 0-Value;
  412. }
  413. b = TRUE;
  414. try {
  415. *OutValue = Value;
  416. } except(EXCEPTION_EXECUTE_HANDLER) {
  417. b = FALSE;
  418. }
  419. if(!b) {
  420. SetLastError(ERROR_INVALID_PARAMETER);
  421. }
  422. return(b);
  423. }
  424. DWORD
  425. tmbox(
  426. LPCTSTR fmt,
  427. ...
  428. )
  429. {
  430. TCHAR text[1024];
  431. TCHAR caption[256];
  432. va_list vaList;
  433. sapiAssert(fmt);
  434. va_start(vaList, fmt);
  435. wvsprintf(text, fmt, vaList);
  436. va_end(vaList);
  437. *caption = 0;
  438. LoadString(MyModuleHandle, IDS_SETUP, caption, sizeof(caption)/sizeof(TCHAR));
  439. sapiAssert(*caption);
  440. return MessageBox(WizardDialogHandle,
  441. text,
  442. caption,
  443. MB_ICONINFORMATION | MB_OK);
  444. }
  445. #ifdef PRERELEASE
  446. #ifdef DBG
  447. HRESULT
  448. FTestForOutstandingCoInits(
  449. VOID
  450. )
  451. /*++
  452. Routine Description: Determines is there was an unitialized call to OleInitialize()
  453. Arguments:
  454. NONE
  455. Return Value:
  456. an HRESULT code
  457. Remarks:
  458. Don't call this function in the release version.
  459. --*/
  460. {
  461. HRESULT hInitRes = ERROR_SUCCESS;
  462. #if defined(UNICODE) || defined(_UNICODE)
  463. // perform a defensive check
  464. hInitRes = CoInitializeEx( NULL, COINIT_MULTITHREADED );
  465. if ( SUCCEEDED(hInitRes) )
  466. {
  467. CoUninitialize();
  468. }
  469. else
  470. {
  471. goto FTestForOutstandingCoInits_Exit;
  472. }
  473. hInitRes = CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
  474. if ( SUCCEEDED(hInitRes) )
  475. {
  476. CoUninitialize();
  477. }
  478. else
  479. {
  480. goto FTestForOutstandingCoInits_Exit;
  481. }
  482. #endif
  483. // it worked out OK
  484. hInitRes = NOERROR;
  485. goto FTestForOutstandingCoInits_Exit;
  486. FTestForOutstandingCoInits_Exit:
  487. return hInitRes;
  488. }
  489. #endif
  490. #endif