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.

413 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: irprops.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. // irprops.cpp : Defines the initialization routines for the DLL.
  11. //
  12. #include "precomp.hxx"
  13. #include "irprops.h"
  14. #include "irpropsheet.h"
  15. #include "debug.h"
  16. BOOL InitInstance();
  17. INT ExitInstance();
  18. BOOL IsFirstInstance();
  19. INT_PTR WINAPI DoPropertiesA(HWND hwnd, LPCSTR CmdLine);
  20. INT_PTR WINAPI DoPropertiesW(HWND hwnd, LPCWSTR CmdLine);
  21. HINSTANCE gHInst;
  22. //
  23. // This records the current active property sheet window handle created
  24. // by this instance. It is set/reset by CIrPropSheet object.
  25. //
  26. HWND g_hwndPropSheet = NULL;
  27. HANDLE g_hMutex = NULL;
  28. BOOL g_bFirstInstance = TRUE;
  29. //
  30. // This records our registered message for inter-instances communications
  31. // The message is registered in CIrpropsApp::InitInstance.
  32. //
  33. UINT g_uIPMsg;
  34. #ifdef _DEBUG
  35. #define new DEBUG_NEW
  36. #undef THIS_FILE
  37. static char THIS_FILE[] = __FILE__;
  38. #endif
  39. extern "C" {
  40. BOOL APIENTRY
  41. DllMain(HANDLE hDll,
  42. DWORD dwReason,
  43. LPVOID lpReserved)
  44. {
  45. IRINFO((_T("DllMain reason %x"), dwReason));
  46. switch (dwReason) {
  47. case DLL_PROCESS_ATTACH:
  48. gHInst = (HINSTANCE) hDll;
  49. return InitInstance();
  50. break;
  51. case DLL_PROCESS_DETACH:
  52. return ExitInstance();
  53. break;
  54. case DLL_THREAD_DETACH:
  55. break;
  56. case DLL_THREAD_ATTACH:
  57. break;
  58. default:
  59. break;
  60. }
  61. return TRUE;
  62. }
  63. }
  64. ////////////////////////////////////////////////////////////////////////
  65. //some globals
  66. APPLETS IRApplet[NUM_APPLETS] = {
  67. {IDI_IRPROPS, IDS_APPLETNAME, IDS_APPLETDESC}
  68. };
  69. /////////////////////////////////////////////////////////////////////////
  70. // CPlApplet function for the control panel
  71. //
  72. LONG CALLBACK CPlApplet(
  73. HWND hwndCPL,
  74. UINT uMsg,
  75. LPARAM lParam1,
  76. LPARAM lParam2)
  77. {
  78. int i;
  79. LPCPLINFO lpCPlInfo;
  80. i = (int) lParam1;
  81. IRINFO((_T("CplApplet message %x"), uMsg));
  82. switch (uMsg)
  83. {
  84. case CPL_INIT: // first message, sent once
  85. if (!IrPropSheet::IsIrDASupported()) {
  86. HPSXA hpsxa;
  87. //
  88. // Check for any installed extensions.
  89. //
  90. hpsxa = SHCreatePropSheetExtArray(HKEY_LOCAL_MACHINE, sc_szRegWireless, 8);
  91. if (hpsxa) {
  92. //
  93. // We have extensions installed so we have to show the CPL,
  94. // whether IRDA exists or not.
  95. //
  96. SHDestroyPropSheetExtArray(hpsxa);
  97. return TRUE;
  98. }
  99. return FALSE;
  100. }
  101. return TRUE;
  102. case CPL_GETCOUNT: // second message, sent once
  103. return NUM_APPLETS;
  104. break;
  105. case CPL_INQUIRE: // third message, sent once per application
  106. if (i < NUM_APPLETS) {
  107. lpCPlInfo = (LPCPLINFO) lParam2;
  108. lpCPlInfo->lData = 0;
  109. lpCPlInfo->idIcon = IRApplet[i].icon;
  110. lpCPlInfo->idName = IRApplet[i].namestring;
  111. lpCPlInfo->idInfo = IRApplet[i].descstring;
  112. } else {
  113. return 1;
  114. }
  115. break;
  116. case CPL_STARTWPARMSA:
  117. if (-1 == DoPropertiesA(hwndCPL, (LPCSTR)lParam2))
  118. MsgBoxWinError(hwndCPL);
  119. // return true so that we won't get CPL_DBLCLK.
  120. return 1;
  121. break;
  122. case CPL_STARTWPARMSW:
  123. if (-1 == DoPropertiesW(hwndCPL, (LPCWSTR)lParam2))
  124. MsgBoxWinError(hwndCPL);
  125. // return true so that we won't get CPL_DBLCLK.
  126. return 1;
  127. break;
  128. case CPL_DBLCLK: // application icon double-clicked
  129. if (-1 == DoPropertiesA(hwndCPL, (LPCSTR)lParam2))
  130. MsgBoxWinError(hwndCPL);
  131. return 1;
  132. break;
  133. case CPL_STOP: // sent once per application before CPL_EXIT
  134. break;
  135. case CPL_EXIT: // sent once before FreeLibrary is called
  136. break;
  137. default:
  138. break;
  139. }
  140. return 0;
  141. }
  142. //
  143. // This function presents the Wireless link property sheet.
  144. // INPUT:
  145. // hwndParent -- window handle to be used as parent window of
  146. // the property sheet
  147. // lpCmdLine -- optional command line
  148. // 'n" (n in decimal) is start page number(zero-based).
  149. // OUTPUT:
  150. // Return value of PropertySheet API
  151. INT_PTR
  152. DoPropertiesW(
  153. HWND hwndParent,
  154. LPCWSTR lpCmdLine
  155. )
  156. {
  157. INT_PTR Result;
  158. INT StartPage;
  159. IRINFO((_T("DoPropertiesW")));
  160. //
  161. // Assuming no start page was specified.
  162. //
  163. StartPage = -1;
  164. //
  165. // Command line specifies start page number
  166. //
  167. if (lpCmdLine)
  168. {
  169. // skip white chars
  170. while (_T('\0') != *lpCmdLine &&
  171. (_T(' ') == *lpCmdLine || _T('\t') == *lpCmdLine))
  172. {
  173. lpCmdLine++;
  174. }
  175. if (_T('0') <= *lpCmdLine && _T('9') >= *lpCmdLine)
  176. {
  177. StartPage = 0;
  178. do
  179. {
  180. StartPage = StartPage * 10 + *lpCmdLine - _T('0');
  181. lpCmdLine++;
  182. } while (_T('0') <= *lpCmdLine && _T('9') >= *lpCmdLine);
  183. }
  184. }
  185. if (!IsFirstInstance() || NULL != g_hwndPropSheet)
  186. {
  187. IRINFO((_T("Not the first instance")));
  188. HWND hwndPropSheet = HWND_DESKTOP;
  189. if (NULL == g_hwndPropSheet)
  190. {
  191. IRINFO((_T("No window created")));
  192. //
  193. // We are not the first instance. Look for the property sheet
  194. // window created by the first instance.
  195. //
  196. EnumWindows(EnumWinProc, (LPARAM)&hwndPropSheet);
  197. }
  198. else
  199. {
  200. IRINFO((_T("Window active")));
  201. //
  202. // This is not the first call and we have a
  203. // property sheet active(same process, multiple calls)
  204. //
  205. hwndPropSheet = g_hwndPropSheet;
  206. }
  207. if (HWND_DESKTOP != hwndPropSheet)
  208. {
  209. IRINFO((_T("Found the active property sheet.")));
  210. //
  211. // We found the active property sheet
  212. //
  213. // Select the new active page if necessary
  214. //
  215. if (-1 != StartPage)
  216. PropSheet_SetCurSel(hwndPropSheet, NULL, StartPage);
  217. //
  218. // bring the property sheet to the foreground.
  219. //
  220. ::SetForegroundWindow(hwndPropSheet);
  221. }
  222. Result = IDCANCEL;
  223. }
  224. else
  225. {
  226. IRINFO((_T("First instance, creating propertysheet")));
  227. IrPropSheet PropSheet(gHInst, IDS_APPLETNAME, hwndParent, StartPage);
  228. }
  229. return Result;
  230. }
  231. //
  232. // This is our callback function for EnumWindows API.
  233. // It probes for each window handle to see if it is the property sheet
  234. // window created by the previous instance. If it is, it returns
  235. // the window handle in the provided buffer, lParam)
  236. // Input:
  237. // hWnd -- the window handle
  238. // lParam -- (HWND *)
  239. // Output:
  240. // TRUE -- Let Windows continue to call us
  241. // FALSE -- Stop Windows from calling us again
  242. //
  243. BOOL
  244. CALLBACK
  245. EnumWinProc(
  246. HWND hWnd,
  247. LPARAM lParam
  248. )
  249. {
  250. //
  251. // Verify with this window to see if it is the one we are looking for.
  252. //
  253. LRESULT lr;
  254. lr = ::SendMessage(hWnd, g_uIPMsg, (WPARAM)IPMSG_SIGNATURECHECK,
  255. (LPARAM)IPMSG_REQUESTSIGNATURE);
  256. if (IPMSG_REPLYSIGNATURE == lr)
  257. {
  258. if (lParam)
  259. {
  260. // this is the one
  261. *((HWND *)(lParam)) = hWnd;
  262. }
  263. //
  264. // We are done with enumeration.
  265. //
  266. return FALSE;
  267. }
  268. return TRUE;
  269. }
  270. INT_PTR
  271. DoPropertiesA(
  272. HWND hwndParent,
  273. LPCSTR lpCmdLine
  274. )
  275. {
  276. WCHAR CmdLineW[MAX_PATH];
  277. UINT Size;
  278. if (!lpCmdLine)
  279. return DoPropertiesW(hwndParent, NULL);
  280. Size=MultiByteToWideChar(CP_ACP, 0, lpCmdLine, -1, CmdLineW, sizeof(CmdLineW) / sizeof(WCHAR));
  281. if (Size == 0) {
  282. return -1;
  283. }
  284. return DoPropertiesW(hwndParent, CmdLineW);
  285. }
  286. // This function creates and displays a message box for the given
  287. // win32 error(or last error)
  288. // INPUT:
  289. // hwndParent -- the parent window for the will-be-created message box
  290. // Type -- message styles(MB_xxxx)
  291. // Error -- Error code. If the value is 0
  292. // GetLastError() will be called to retreive the
  293. // real error code.
  294. // CaptionId -- optional string id for caption
  295. // OUTPUT:
  296. // the value return from MessageBox
  297. //
  298. int
  299. MsgBoxWinError(
  300. HWND hwndParent,
  301. DWORD Options,
  302. DWORD Error,
  303. int CaptionId
  304. )
  305. {
  306. int ResourceSize=0;
  307. if (ERROR_SUCCESS == Error)
  308. Error = GetLastError();
  309. // nonsense to report success!
  310. if (ERROR_SUCCESS == Error)
  311. return IDOK;
  312. TCHAR szMsg[MAX_PATH];
  313. TCHAR szCaption[MAX_PATH];
  314. if (!CaptionId)
  315. CaptionId = IDS_APPLETNAME;
  316. ResourceSize=LoadString(gHInst, CaptionId, szCaption, sizeof(szCaption) / sizeof(TCHAR));
  317. if (ResourceSize != 0) {
  318. ResourceSize=FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
  319. NULL, Error, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
  320. szMsg, sizeof(szMsg) / sizeof(TCHAR), NULL);
  321. if (ResourceSize != 0) {
  322. return MessageBox(hwndParent, szMsg, szCaption, Options);
  323. }
  324. }
  325. #if DBG
  326. OutputDebugStringA("IRPROPS:MsgBoxWinError(): could not load resource\n");
  327. #endif
  328. return 0;
  329. }
  330. BOOL InitInstance()
  331. {
  332. //
  333. // Try to create a named mutex. This give us a clue
  334. // if we are the first instance. We will not close
  335. // the mutex until exit.
  336. //
  337. g_hMutex = CreateMutex(NULL, TRUE, SINGLE_INST_MUTEX);
  338. if (g_hMutex)
  339. {
  340. g_bFirstInstance = ERROR_ALREADY_EXISTS != GetLastError();
  341. //
  342. // register a message for inter-instances communication
  343. //
  344. g_uIPMsg = RegisterWindowMessage(WIRELESSLINK_INTERPROCESSMSG);
  345. SHFusionInitializeFromModuleID(gHInst, 124);
  346. return TRUE;
  347. }
  348. return FALSE;
  349. }
  350. BOOL ExitInstance()
  351. {
  352. if (g_hMutex)
  353. {
  354. CloseHandle(g_hMutex);
  355. g_hMutex = NULL;
  356. }
  357. SHFusionUninitialize();
  358. return TRUE;
  359. }
  360. BOOL IsFirstInstance()
  361. {
  362. return g_bFirstInstance;
  363. }