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.

884 lines
20 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. //
  4. // the following is not in the SDK
  5. //
  6. #include <pshpack2.h>
  7. #include <poppack.h>
  8. #include <winuserp.h>
  9. //
  10. // When Winnt32.exe is launched over a network, these two parameters have valid
  11. // values and need to be taken into consideration before displaying any dialog box
  12. //
  13. extern HWND Winnt32Dlg;
  14. extern HANDLE WinNT32StubEvent;
  15. PCTSTR
  16. GetStringResource (
  17. IN UINT Id
  18. )
  19. {
  20. LONG rc;
  21. PCTSTR MsgBuf;
  22. if (HIWORD (Id)) {
  23. // From string
  24. rc = FormatMessage (
  25. FORMAT_MESSAGE_ALLOCATE_BUFFER|
  26. FORMAT_MESSAGE_ARGUMENT_ARRAY|
  27. FORMAT_MESSAGE_FROM_STRING,
  28. UIntToPtr( Id ),
  29. 0,
  30. 0,
  31. (PVOID) &MsgBuf,
  32. 0,
  33. NULL
  34. );
  35. }
  36. else {
  37. // From resource
  38. rc = FormatMessage (
  39. FORMAT_MESSAGE_ALLOCATE_BUFFER|
  40. FORMAT_MESSAGE_ARGUMENT_ARRAY|
  41. FORMAT_MESSAGE_FROM_HMODULE,
  42. (PVOID) hInst,
  43. (DWORD) Id,
  44. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  45. (LPVOID) &MsgBuf,
  46. 0,
  47. NULL
  48. );
  49. }
  50. if (rc == 0) {
  51. return NULL;
  52. }
  53. return MsgBuf;
  54. }
  55. VOID
  56. FreeStringResource (
  57. IN PCTSTR String
  58. )
  59. {
  60. if (String) {
  61. LocalFree ((HLOCAL) String);
  62. }
  63. }
  64. VOID
  65. SaveTextForSMS(
  66. IN PCTSTR Buffer
  67. )
  68. {
  69. CHAR AnsiBuffer[5000];
  70. if(LastMessage) {
  71. FREE( LastMessage );
  72. }
  73. #ifdef UNICODE
  74. WideCharToMultiByte(
  75. CP_ACP,
  76. 0,
  77. Buffer,
  78. -1,
  79. AnsiBuffer,
  80. sizeof(AnsiBuffer),
  81. NULL,
  82. NULL
  83. );
  84. if(LastMessage = MALLOC(strlen(AnsiBuffer)+1)) {
  85. strcpy( LastMessage, AnsiBuffer);
  86. }
  87. #else
  88. LastMessage = DupString( Buffer );
  89. #endif
  90. }
  91. VOID
  92. SaveMessageForSMS(
  93. IN DWORD MessageId,
  94. ...
  95. )
  96. {
  97. va_list arglist;
  98. TCHAR Buffer[5000];
  99. va_start(arglist,MessageId);
  100. FormatMessage(
  101. FORMAT_MESSAGE_FROM_HMODULE,
  102. hInst,
  103. MessageId,
  104. 0,
  105. Buffer,
  106. sizeof(Buffer) / sizeof(TCHAR),
  107. &arglist
  108. );
  109. SaveTextForSMS(Buffer);
  110. va_end(arglist);
  111. }
  112. int
  113. MessageBoxFromMessageV(
  114. IN HWND Window,
  115. IN DWORD MessageId,
  116. IN BOOL SystemMessage,
  117. IN DWORD CaptionStringId,
  118. IN UINT Style,
  119. IN va_list *Args
  120. )
  121. {
  122. TCHAR Caption[512];
  123. TCHAR Buffer[5000];
  124. HWND Parent;
  125. if(!LoadString(hInst,CaptionStringId,Caption,sizeof(Caption)/sizeof(TCHAR))) {
  126. Caption[0] = 0;
  127. }
  128. FormatMessage(
  129. SystemMessage ? FORMAT_MESSAGE_FROM_SYSTEM : FORMAT_MESSAGE_FROM_HMODULE,
  130. hInst,
  131. MessageId,
  132. 0,
  133. Buffer,
  134. sizeof(Buffer) / sizeof(TCHAR),
  135. Args
  136. );
  137. SaveTextForSMS(Buffer);
  138. //
  139. // In batch mode, we don't want to wait on the user.
  140. //
  141. if(BatchMode) {
  142. if( Style & MB_YESNO ) {
  143. return( IDYES );
  144. } else {
  145. return( IDOK );
  146. }
  147. }
  148. //
  149. // Force ourselves into the foreground manually to guarantee that we get
  150. // a chance to set our palette. Otherwise the message box gets the
  151. // palette messages and color in our background bitmap can get hosed.
  152. // We assume the parent is a wizard page.
  153. //
  154. if(Window && IsWindow(Window)) {
  155. Parent = GetParent(Window);
  156. if(!Parent) {
  157. Parent = Window;
  158. }
  159. } else {
  160. Parent = NULL;
  161. }
  162. SetForegroundWindow(Parent);
  163. //
  164. // If we're just checking upgrades
  165. // then throw this message into the compatibility list.
  166. // NOTE: there's no reason not ot do this on Win9x as well
  167. //
  168. if( CheckUpgradeOnly) {
  169. PCOMPATIBILITY_DATA CompData;
  170. CompData = (PCOMPATIBILITY_DATA) MALLOC( sizeof(COMPATIBILITY_DATA) );
  171. if (CompData == NULL) {
  172. return 0;
  173. }
  174. ZeroMemory( CompData, sizeof(COMPATIBILITY_DATA) );
  175. CompData->Description = DupString( Buffer );
  176. CompData->Flags = COMPFLAG_STOPINSTALL;
  177. if( !CompatibilityData.Flink ) {
  178. InitializeListHead( &CompatibilityData );
  179. }
  180. InsertTailList( &CompatibilityData, &CompData->ListEntry );
  181. CompatibilityCount++;
  182. IncompatibilityStopsInstallation = TRUE;
  183. if( Style & MB_YESNO ) {
  184. return( IDYES );
  185. } else {
  186. return( IDOK );
  187. }
  188. }
  189. //
  190. // always make sure the window is visible
  191. //
  192. if (Window && !IsWindowVisible (Window)) {
  193. //
  194. // if this window is the wizard handle or one of its pages
  195. // then use a special message to restore it
  196. //
  197. if (WizardHandle &&
  198. (WizardHandle == Window || IsChild (WizardHandle, Window))
  199. ) {
  200. SendMessage(WizardHandle, WMX_BBTEXT, (WPARAM)FALSE, 0);
  201. } else {
  202. //
  203. // the window is one of the billboard windows;
  204. // just leave it alone or weird things may happen
  205. //
  206. }
  207. }
  208. return(MessageBox(Window,Buffer,Caption,Style));
  209. }
  210. int
  211. MessageBoxFromMessage(
  212. IN HWND Window,
  213. IN DWORD MessageId,
  214. IN BOOL SystemMessage,
  215. IN DWORD CaptionStringId,
  216. IN UINT Style,
  217. ...
  218. )
  219. {
  220. va_list arglist;
  221. int i;
  222. //
  223. // before displaying any dialog, make sure Winnt32.exe wait dialog is gone
  224. //
  225. if (Winnt32Dlg) {
  226. DestroyWindow (Winnt32Dlg);
  227. Winnt32Dlg = NULL;
  228. }
  229. if (WinNT32StubEvent) {
  230. SetEvent (WinNT32StubEvent);
  231. WinNT32StubEvent = NULL;
  232. }
  233. va_start(arglist,Style);
  234. i = MessageBoxFromMessageV(Window,MessageId,SystemMessage,CaptionStringId,Style,&arglist);
  235. va_end(arglist);
  236. return(i);
  237. }
  238. int
  239. MessageBoxFromMessageWithSystem(
  240. IN HWND Window,
  241. IN DWORD MessageId,
  242. IN DWORD CaptionStringId,
  243. IN UINT Style,
  244. IN HMODULE hMod
  245. )
  246. {
  247. TCHAR Caption[512];
  248. TCHAR Buffer[5000];
  249. HWND Parent;
  250. DWORD i;
  251. if(!LoadString(hInst,CaptionStringId,Caption,sizeof(Caption)/sizeof(TCHAR))) {
  252. Caption[0] = 0;
  253. }
  254. i = FormatMessage(
  255. FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE,
  256. hMod,
  257. MessageId,
  258. 0,
  259. Buffer,
  260. sizeof(Buffer) / sizeof(TCHAR),
  261. NULL
  262. );
  263. if (i == 0) {
  264. return -1;
  265. }
  266. SaveTextForSMS(Buffer);
  267. //
  268. // In batch mode, we don't want to wait on the user.
  269. //
  270. if(BatchMode) {
  271. if( Style & MB_YESNO ) {
  272. return( IDYES );
  273. } else {
  274. return( IDOK );
  275. }
  276. }
  277. //
  278. // Force ourselves into the foreground manually to guarantee that we get
  279. // a chance to set our palette. Otherwise the message box gets the
  280. // palette messages and color in our background bitmap can get hosed.
  281. // We assume the parent is a wizard page.
  282. //
  283. if(Window && IsWindow(Window)) {
  284. Parent = GetParent(Window);
  285. if(!Parent) {
  286. Parent = Window;
  287. }
  288. } else {
  289. Parent = NULL;
  290. }
  291. SetForegroundWindow(Parent);
  292. return(MessageBox(Window,Buffer,Caption,Style));
  293. }
  294. int
  295. MessageBoxFromMessageAndSystemError(
  296. IN HWND Window,
  297. IN DWORD MessageId,
  298. IN DWORD SystemMessageId,
  299. IN DWORD CaptionStringId,
  300. IN UINT Style,
  301. ...
  302. )
  303. {
  304. va_list arglist;
  305. TCHAR Caption[500];
  306. TCHAR Buffer1[2000];
  307. TCHAR Buffer2[1000];
  308. int i;
  309. //
  310. // Fetch the non-system part. The arguments are for that part of the
  311. // message -- the system part has no inserts.
  312. //
  313. va_start(arglist,Style);
  314. FormatMessage(
  315. FORMAT_MESSAGE_FROM_HMODULE,
  316. hInst,
  317. MessageId,
  318. 0,
  319. Buffer1,
  320. sizeof(Buffer1) / sizeof(TCHAR),
  321. &arglist
  322. );
  323. va_end(arglist);
  324. //
  325. // Now fetch the system part.
  326. //
  327. i = (int)FormatMessage(
  328. FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  329. NULL,
  330. SystemMessageId,
  331. 0,
  332. Buffer2,
  333. sizeof(Buffer2) / sizeof(TCHAR),
  334. NULL
  335. );
  336. if(!i) {
  337. FormatMessage(
  338. FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ARGUMENT_ARRAY,
  339. hInst,
  340. MSG_UNKNOWN_SYSTEM_ERROR,
  341. 0,
  342. Buffer2,
  343. sizeof(Buffer2) / sizeof(TCHAR),
  344. (va_list *)&SystemMessageId
  345. );
  346. }
  347. //
  348. // Now display the message, which is made up of two parts that get
  349. // inserted into MSG_ERROR_WITH_SYSTEM_ERROR.
  350. //
  351. i = MessageBoxFromMessage(
  352. Window,
  353. MSG_ERROR_WITH_SYSTEM_ERROR,
  354. FALSE,
  355. CaptionStringId,
  356. Style,
  357. Buffer1,
  358. Buffer2
  359. );
  360. return(i);
  361. }
  362. HPALETTE
  363. CreateDIBPalette(
  364. IN LPBITMAPINFO BitmapInfo,
  365. OUT int *ColorCount
  366. )
  367. /*++
  368. Routine Description:
  369. Arguments:
  370. Return Value:
  371. --*/
  372. {
  373. LPBITMAPINFOHEADER BitmapInfoHeader;
  374. LPLOGPALETTE LogicalPalette;
  375. HPALETTE Palette;
  376. int i;
  377. DWORD d;
  378. BitmapInfoHeader = (LPBITMAPINFOHEADER)BitmapInfo;
  379. //
  380. // No palette needed for >= 16 bpp
  381. //
  382. *ColorCount = (BitmapInfoHeader->biBitCount <= 8)
  383. ? (1 << BitmapInfoHeader->biBitCount)
  384. : 0;
  385. if(*ColorCount) {
  386. LogicalPalette = MALLOC(sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * (*ColorCount)));
  387. if(!LogicalPalette) {
  388. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  389. return(NULL);
  390. }
  391. LogicalPalette->palVersion = 0x300;
  392. LogicalPalette->palNumEntries = (WORD)*ColorCount;
  393. for(i=0; i<*ColorCount; i++) {
  394. LogicalPalette->palPalEntry[i].peRed = BitmapInfo->bmiColors[i].rgbRed;
  395. LogicalPalette->palPalEntry[i].peGreen = BitmapInfo->bmiColors[i].rgbGreen;
  396. LogicalPalette->palPalEntry[i].peBlue = BitmapInfo->bmiColors[i].rgbBlue;
  397. LogicalPalette->palPalEntry[i].peFlags = 0;
  398. }
  399. Palette = CreatePalette(LogicalPalette);
  400. d = GetLastError();
  401. FREE(LogicalPalette);
  402. SetLastError(d);
  403. } else {
  404. Palette = NULL;
  405. }
  406. return(Palette);
  407. }
  408. HBITMAP
  409. LoadResourceBitmap(
  410. IN HINSTANCE hInst,
  411. IN LPCTSTR Id,
  412. OUT HPALETTE *Palette
  413. )
  414. /*++
  415. Routine Description:
  416. Bitmaps in resources are stored as DIBs. When fetched via LoadBitmap()
  417. they are converted to DDBs and a color conversion takes place based on
  418. whatever logical palette happens to be currently selected into whatever
  419. DC gets used internally for the conversion.
  420. This routine fetches the color data from the DIB in the resources and
  421. ensures that the DIB is converted into a DDB using accurate color data.
  422. It is essentially a color-accurate replacement for LoadBitmap().
  423. Arguments:
  424. hInst - supplies instance handle for module containing the bitmap resource.
  425. Id - supplies the id of the bitmap resource.
  426. Palette - if successful, receives a handle to a palette for the bitmap.
  427. Return Value:
  428. If successful, handle to the loaded bitmap (DIB).
  429. If not, NULL is returned. Check GetLastError().
  430. --*/
  431. {
  432. DWORD d;
  433. BOOL b;
  434. HRSRC BlockHandle;
  435. HGLOBAL MemoryHandle;
  436. BITMAPINFOHEADER *BitmapInfoHeader;
  437. HDC hdc;
  438. int ColorCount;
  439. HBITMAP Bitmap;
  440. HPALETTE PreviousPalette;
  441. Bitmap = NULL;
  442. BlockHandle = FindResource(hInst,Id,RT_BITMAP);
  443. if(!BlockHandle) {
  444. d = GetLastError();
  445. goto c0;
  446. }
  447. MemoryHandle = LoadResource(hInst,BlockHandle);
  448. if(!MemoryHandle) {
  449. d = GetLastError();
  450. goto c0;
  451. }
  452. BitmapInfoHeader = LockResource(MemoryHandle);
  453. if(!BitmapInfoHeader) {
  454. d = GetLastError();
  455. goto c1;
  456. }
  457. hdc = GetDC(NULL);
  458. if(!hdc) {
  459. d = GetLastError();
  460. goto c2;
  461. }
  462. #if 0 // steveow - fix palette problem
  463. if(*Palette = CreateDIBPalette((BITMAPINFO *)BitmapInfoHeader,&ColorCount)) {
  464. PreviousPalette = SelectPalette(hdc,*Palette,FALSE);
  465. RealizePalette(hdc);
  466. } else {
  467. PreviousPalette = NULL;
  468. }
  469. #else
  470. ColorCount = 16;
  471. PreviousPalette = NULL;
  472. #endif
  473. //
  474. // This routine creates a DDB from the DIB (the name is confusing).
  475. //
  476. Bitmap = CreateDIBitmap(
  477. hdc,
  478. BitmapInfoHeader,
  479. CBM_INIT,
  480. (LPBYTE)BitmapInfoHeader + BitmapInfoHeader->biSize + (ColorCount * sizeof(RGBQUAD)),
  481. (BITMAPINFO *)BitmapInfoHeader,
  482. DIB_RGB_COLORS
  483. );
  484. if(!Bitmap) {
  485. d = GetLastError();
  486. goto c3;
  487. }
  488. c3:
  489. if(PreviousPalette) {
  490. SelectObject(hdc,PreviousPalette);
  491. }
  492. if(!Bitmap) {
  493. DeleteObject(*Palette);
  494. *Palette = NULL;
  495. }
  496. ReleaseDC(NULL,hdc);
  497. c2:
  498. UnlockResource(MemoryHandle);
  499. c1:
  500. FreeResource(MemoryHandle);
  501. c0:
  502. if(!Bitmap) {
  503. SetLastError(d);
  504. }
  505. return(Bitmap);
  506. }
  507. BOOL
  508. GetBitmapDataAndPalette(
  509. IN HINSTANCE hInst,
  510. IN LPCTSTR Id,
  511. OUT HPALETTE *Palette,
  512. OUT PUINT ColorCount,
  513. OUT CONST BITMAPINFOHEADER **BitmapData
  514. )
  515. /*++
  516. Routine Description:
  517. Retreives device-independent bitmap data and a color table from a
  518. bitmap in a resource.
  519. Arguments:
  520. hInst - supplies instance handle for module containing the bitmap resource.
  521. Id - supplies the id of the bitmap resource.
  522. Palette - if successful, receives a handle to a palette for the bitmap.
  523. ColorCount - if successful, receives the number of entries in the
  524. palette for the bitmap.
  525. BitmapData - if successful, receives a pointer to the bitmap info
  526. header structure in the resources. This is in read-only memory
  527. so the caller should not try to modify it.
  528. Return Value:
  529. If successful, handle to the loaded bitmap (DIB).
  530. If not, NULL is returned. Check GetLastError().
  531. --*/
  532. {
  533. HRSRC BlockHandle;
  534. HGLOBAL MemoryHandle;
  535. //
  536. // None of FindResource(), LoadResource(), or LockResource()
  537. // need to have cleanup routines called in Win32.
  538. //
  539. BlockHandle = FindResource(hInst,Id,RT_BITMAP);
  540. if(!BlockHandle) {
  541. return(FALSE);
  542. }
  543. MemoryHandle = LoadResource(hInst,BlockHandle);
  544. if(!MemoryHandle) {
  545. return(FALSE);
  546. }
  547. *BitmapData = LockResource(MemoryHandle);
  548. if(*BitmapData == NULL) {
  549. return(FALSE);
  550. }
  551. *Palette = CreateDIBPalette((LPBITMAPINFO)*BitmapData,ColorCount);
  552. return(TRUE);
  553. }
  554. PVOID
  555. FindControlInDialog(
  556. IN PVOID Template,
  557. IN UINT ControlId
  558. )
  559. {
  560. PVOID p;
  561. DLGTEMPLATE *pTemplate;
  562. DLGTEMPLATE2 *pTemplate2;
  563. DLGITEMTEMPLATE *pItem;
  564. DLGITEMTEMPLATE2 *pItem2;
  565. WORD ItemCount;
  566. DWORD Style;
  567. WORD i;
  568. BOOL bDialogEx;
  569. if (!Template) // validate
  570. return NULL;
  571. p = Template;
  572. //
  573. // Skip fixed part of template
  574. //
  575. if(((DLGTEMPLATE2 *)p)->wSignature == 0xffff) {
  576. pTemplate2 = p;
  577. ItemCount = pTemplate2->cDlgItems;
  578. Style = pTemplate2->style;
  579. p = pTemplate2 + 1;
  580. bDialogEx = TRUE;
  581. } else {
  582. pTemplate = p;
  583. ItemCount = pTemplate->cdit;
  584. Style = pTemplate->style;
  585. p = pTemplate + 1;
  586. bDialogEx = FALSE;
  587. }
  588. //
  589. // Skip menu. First word=0 means no menu
  590. // First word=0xffff means one more word follows
  591. // Else it's a nul-terminated string
  592. //
  593. switch(*(WORD *)p) {
  594. case 0xffff:
  595. p = (WORD *)p + 2;
  596. break;
  597. case 0:
  598. p = (WORD *)p + 1;
  599. break;
  600. default:
  601. p = (PWCHAR)p + lstrlenW(p) + 1;
  602. break;
  603. }
  604. //
  605. // Skip class, similar to menu
  606. //
  607. switch(*(WORD *)p) {
  608. case 0xffff:
  609. p = (WORD *)p + 2;
  610. break;
  611. case 0:
  612. p = (WORD *)p + 1;
  613. break;
  614. default:
  615. p = (PWCHAR)p + lstrlenW(p) + 1;
  616. break;
  617. }
  618. //
  619. // Skip title
  620. //
  621. p = (PWCHAR)p + lstrlenW(p) + 1;
  622. if(Style & DS_SETFONT) {
  623. //
  624. // Skip point size and typeface name
  625. //
  626. p = (WORD *)p + 1;
  627. if (bDialogEx)
  628. {
  629. // Skip weight, italic, and charset.
  630. p = (WORD *)p + 1;
  631. p = (BYTE *)p + 1;
  632. p = (BYTE *)p + 1;
  633. }
  634. p = (PWCHAR)p + lstrlenW(p) + 1;
  635. }
  636. //
  637. // Now we have a pointer to the first item in the dialog
  638. //
  639. for(i=0; i<ItemCount; i++) {
  640. //
  641. // Align to next DWORD boundary
  642. //
  643. p = (PVOID)(((ULONG_PTR)p + sizeof(DWORD) - 1) & (~((ULONG_PTR)sizeof(DWORD) - 1)));
  644. if (bDialogEx)
  645. {
  646. pItem2 = p;
  647. if(pItem2->dwID == (WORD)ControlId) {
  648. break;
  649. }
  650. //
  651. // Skip to next item in dialog.
  652. // First is class, which is either 0xffff plus one more word,
  653. // or a unicode string. After that is text/title.
  654. //
  655. p = pItem2 + 1;
  656. }
  657. else
  658. {
  659. pItem = p;
  660. if(pItem->id == (WORD)ControlId) {
  661. break;
  662. }
  663. //
  664. // Skip to next item in dialog.
  665. // First is class, which is either 0xffff plus one more word,
  666. // or a unicode string. After that is text/title.
  667. //
  668. p = pItem + 1;
  669. }
  670. if(*(WORD *)p == 0xffff) {
  671. p = (WORD *)p + 2;
  672. } else {
  673. p = (PWCHAR)p + lstrlenW(p) + 1;
  674. }
  675. if(*(WORD *)p == 0xffff) {
  676. p = (WORD *)p + 2;
  677. } else {
  678. p = (PWCHAR)p + lstrlenW(p) + 1;
  679. }
  680. //
  681. // Skip creation data.
  682. //
  683. p = (PUCHAR)p + *(WORD *)p;
  684. p = (WORD *)p + 1;
  685. }
  686. if(i == ItemCount) {
  687. p = NULL;
  688. }
  689. return(p);
  690. }
  691. UINT
  692. GetYPositionOfDialogItem(
  693. IN LPCTSTR Dialog,
  694. IN UINT ControlId
  695. )
  696. {
  697. HRSRC hRsrc;
  698. PVOID p;
  699. HGLOBAL hGlobal;
  700. PVOID pItem;
  701. UINT i;
  702. i = 0;
  703. if(hRsrc = FindResource(hInst,Dialog,RT_DIALOG)) {
  704. if(hGlobal = LoadResource(hInst,hRsrc)) {
  705. if(p = LockResource(hGlobal)) {
  706. if(pItem = FindControlInDialog(p,ControlId)) {
  707. if(((DLGTEMPLATE2 *)p)->wSignature == 0xffff) {
  708. i = ((DLGITEMTEMPLATE2*)pItem)->y;
  709. }
  710. else
  711. {
  712. i = ((DLGITEMTEMPLATE*)pItem)->y;
  713. }
  714. }
  715. UnlockResource(hGlobal);
  716. }
  717. FreeResource(hGlobal);
  718. }
  719. }
  720. return(i);
  721. }