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.

412 lines
14 KiB

  1. // wiaacmgr.cpp : Implementation of WinMain
  2. // Note: Proxy/Stub Information
  3. // To build a separate proxy/stub DLL,
  4. // run nmake -f wiaacmgrps.mk in the project directory.
  5. #include "precomp.h"
  6. #include "resource.h"
  7. #include "wiaacmgr.h"
  8. #include <shpriv.h>
  9. #include <shlguid.h>
  10. #include <stdarg.h>
  11. #include "wiaacmgr_i.c"
  12. #include "acqmgr.h"
  13. #include "eventprompt.h"
  14. #include "runwiz.h"
  15. #include <initguid.h>
  16. HINSTANCE g_hInstance;
  17. #if defined(DBG_GENERATE_PRETEND_EVENT)
  18. extern "C" int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
  19. {
  20. WIA_DEBUG_CREATE( hInstance );
  21. SHFusionInitializeFromModuleID( hInstance, 123 );
  22. g_hInstance = hInstance;
  23. HRESULT hr = CoInitialize(NULL);
  24. if (SUCCEEDED(hr))
  25. {
  26. IWiaDevMgr *pIWiaDevMgr = NULL;
  27. hr = CoCreateInstance( CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)&pIWiaDevMgr );
  28. if (SUCCEEDED(hr))
  29. {
  30. BSTR bstrDeviceID;
  31. hr = pIWiaDevMgr->SelectDeviceDlgID( NULL, 0, 0, &bstrDeviceID );
  32. if (hr == S_OK)
  33. {
  34. CEventParameters EventParameters;
  35. EventParameters.EventGUID = WIA_EVENT_DEVICE_CONNECTED;
  36. EventParameters.strEventDescription = L"";
  37. EventParameters.strDeviceID = static_cast<LPCWSTR>(bstrDeviceID);
  38. EventParameters.strDeviceDescription = L"";
  39. EventParameters.ulEventType = 0;
  40. EventParameters.ulReserved = 0;
  41. EventParameters.hwndParent = NULL;
  42. HANDLE hThread = CAcquisitionThread::Create( EventParameters );
  43. if (hThread)
  44. WaitForSingleObject(hThread,INFINITE);
  45. SysFreeString(bstrDeviceID);
  46. }
  47. pIWiaDevMgr->Release();
  48. }
  49. CoUninitialize();
  50. }
  51. SHFusionUninitialize();
  52. WIA_REPORT_LEAKS();
  53. WIA_DEBUG_DESTROY();
  54. return 0;
  55. }
  56. #else // !defined(DBG_GENERATE_PRETEND_EVENT)
  57. const DWORD dwTimeOut = 5000; // time for EXE to be idle before shutting down
  58. const DWORD dwPause = 1000; // time to wait for threads to finish up
  59. // Passed to CreateThread to monitor the shutdown event
  60. static DWORD WINAPI MonitorProc(void* pv)
  61. {
  62. CExeModule* p = (CExeModule*)pv;
  63. p->MonitorShutdown();
  64. return 0;
  65. }
  66. LONG CExeModule::Unlock()
  67. {
  68. LONG l = CComModule::Unlock();
  69. if (l == 0)
  70. {
  71. bActivity = true;
  72. SetEvent(hEventShutdown); // tell monitor that we transitioned to zero
  73. }
  74. return l;
  75. }
  76. //Monitors the shutdown event
  77. void CExeModule::MonitorShutdown()
  78. {
  79. while (1)
  80. {
  81. WaitForSingleObject(hEventShutdown, INFINITE);
  82. DWORD dwWait=0;
  83. do
  84. {
  85. bActivity = false;
  86. dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
  87. } while (dwWait == WAIT_OBJECT_0);
  88. // timed out
  89. if (!bActivity && m_nLockCnt == 0) // if no activity let's really bail
  90. {
  91. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  92. CoSuspendClassObjects();
  93. if (!bActivity && m_nLockCnt == 0)
  94. #endif
  95. break;
  96. }
  97. }
  98. CloseHandle(hEventShutdown);
  99. PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
  100. }
  101. bool CExeModule::StartMonitor()
  102. {
  103. hEventShutdown = CreateEvent(NULL, false, false, NULL);
  104. if (hEventShutdown == NULL)
  105. return false;
  106. DWORD dwThreadID;
  107. HANDLE h = CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
  108. return (h != NULL);
  109. }
  110. CExeModule _Module;
  111. BEGIN_OBJECT_MAP(ObjectMap)
  112. OBJECT_ENTRY(CLSID_AcquisitionManager, CAcquisitionManager)
  113. OBJECT_ENTRY(CLSID_MinimalTransfer, CMinimalTransfer)
  114. OBJECT_ENTRY(WIA_EVENT_HANDLER_PROMPT, CEventPrompt)
  115. OBJECT_ENTRY(CLSID_StiEventHandler, CStiEventHandler)
  116. END_OBJECT_MAP()
  117. LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
  118. {
  119. while (p1 != NULL && *p1 != NULL)
  120. {
  121. LPCTSTR p = p2;
  122. while (p != NULL && *p != NULL)
  123. {
  124. if (*p1 == *p)
  125. return CharNext(p1);
  126. p = CharNext(p);
  127. }
  128. p1 = CharNext(p1);
  129. }
  130. return NULL;
  131. }
  132. static HRESULT RegisterForWiaEvents( LPCWSTR pszDevice, const CLSID &clsidHandler, const IID &iidEvent, int nName, int nDescription, int nIcon, bool bDefault, bool bRegister )
  133. {
  134. WIA_PUSH_FUNCTION((TEXT("RegisterForWiaEvents( device: %ws, default: %d, register: %d )"), pszDevice, bDefault, bRegister ));
  135. WIA_PRINTGUID((clsidHandler,TEXT("Handler:")));
  136. WIA_PRINTGUID((iidEvent,TEXT("Event:")));
  137. CComPtr<IWiaDevMgr> pWiaDevMgr;
  138. HRESULT hr = CoCreateInstance( CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_NO_FAILURE_LOG, IID_IWiaDevMgr, (void**)&pWiaDevMgr );
  139. if (SUCCEEDED(hr))
  140. {
  141. CSimpleBStr bstrDeviceId(pszDevice);
  142. CSimpleBStr bstrName(CSimpleString(nName,_Module.m_hInst));
  143. CSimpleBStr bstrDescription(CSimpleString(nDescription,_Module.m_hInst));
  144. CSimpleBStr bstrIcon(CSimpleString(nIcon,_Module.m_hInst));
  145. WIA_TRACE((TEXT("device: %ws"), pszDevice ));
  146. WIA_TRACE((TEXT("name : %ws"), bstrName.BString() ));
  147. WIA_TRACE((TEXT("desc : %ws"), bstrDescription.BString() ));
  148. WIA_TRACE((TEXT("icon : %ws"), bstrIcon.BString() ));
  149. if (bRegister)
  150. {
  151. if (bstrName.BString() && bstrDescription.BString() && bstrIcon.BString())
  152. {
  153. hr = pWiaDevMgr->RegisterEventCallbackCLSID(
  154. WIA_REGISTER_EVENT_CALLBACK,
  155. pszDevice ? bstrDeviceId.BString() : NULL,
  156. &iidEvent,
  157. &clsidHandler,
  158. bstrName,
  159. bstrDescription,
  160. bstrIcon
  161. );
  162. if (SUCCEEDED(hr) && bDefault)
  163. {
  164. hr = pWiaDevMgr->RegisterEventCallbackCLSID(
  165. WIA_SET_DEFAULT_HANDLER,
  166. pszDevice ? bstrDeviceId.BString() : NULL,
  167. &iidEvent,
  168. &clsidHandler,
  169. bstrName,
  170. bstrDescription,
  171. bstrIcon
  172. );
  173. if (FAILED(hr))
  174. {
  175. WIA_PRINTHRESULT((hr,TEXT("WIA_SET_DEFAULT_HANDLER failed")));
  176. }
  177. }
  178. else if (FAILED(hr))
  179. {
  180. WIA_PRINTHRESULT((hr,TEXT("WIA_REGISTER_EVENT_CALLBACK failed")));
  181. }
  182. }
  183. }
  184. else
  185. {
  186. hr = pWiaDevMgr->RegisterEventCallbackCLSID(
  187. WIA_UNREGISTER_EVENT_CALLBACK,
  188. pszDevice ? bstrDeviceId.BString() : NULL,
  189. &iidEvent,
  190. &clsidHandler,
  191. bstrName,
  192. bstrDescription,
  193. bstrIcon
  194. );
  195. if (FAILED(hr))
  196. {
  197. WIA_PRINTHRESULT((hr,TEXT("WIA_SET_DEFAULT_HANDLER failed")));
  198. }
  199. }
  200. }
  201. if (FAILED(hr))
  202. {
  203. WIA_PRINTHRESULT((hr,TEXT("Unable to register for the event!")));
  204. }
  205. return hr;
  206. }
  207. /////////////////////////////////////////////////////////////////////////////
  208. //
  209. extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
  210. HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
  211. {
  212. //
  213. // Save the global hInstance
  214. //
  215. g_hInstance = hInstance;
  216. //
  217. // Create the debugger
  218. //
  219. WIA_DEBUG_CREATE( hInstance );
  220. //
  221. // this line necessary for _ATL_MIN_CRT
  222. //
  223. lpCmdLine = GetCommandLine();
  224. //
  225. // Initialize fusion
  226. //
  227. SHFusionInitializeFromModuleID( hInstance, 123 );
  228. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  229. HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  230. #else
  231. HRESULT hRes = CoInitialize(NULL);
  232. #endif
  233. int nRet = 0;
  234. if (SUCCEEDED(hRes))
  235. {
  236. _Module.Init(ObjectMap, hInstance, &LIBID_WIAACMGRLib);
  237. _Module.dwThreadID = GetCurrentThreadId();
  238. TCHAR szTokens[] = _T("-/");
  239. //
  240. // Assume we'll be running as a server
  241. //
  242. BOOL bRun = TRUE;
  243. //
  244. // Assume we won't be selecting a device and running the wizard
  245. //
  246. BOOL bRunWizard = FALSE;
  247. //
  248. // If there are no switches, we are not going to run the server
  249. //
  250. int nSwitchCount = 0;
  251. LPCTSTR lpszToken = FindOneOf( lpCmdLine, szTokens );
  252. while (lpszToken != NULL)
  253. {
  254. //
  255. // One more switch. If we don't have any, we are going to do the selection dialog instead.
  256. //
  257. nSwitchCount++;
  258. if (CSimpleString(lpszToken).CompareNoCase(_T("RegServer"))==0)
  259. {
  260. //
  261. // Register the server
  262. //
  263. hRes = _Module.UpdateRegistryFromResource(IDR_ACQUISITIONMANAGER, TRUE);
  264. _Module.UpdateRegistryFromResource(IDR_MINIMALTRANSFER,TRUE);
  265. _Module.UpdateRegistryFromResource(IDR_STIEVENTHANDLER,TRUE);
  266. nRet = _Module.RegisterServer(TRUE);
  267. hRes = RegisterForWiaEvents( NULL, CLSID_AcquisitionManager, WIA_EVENT_DEVICE_CONNECTED, IDS_DOWNLOADMANAGER_NAME, IDS_DOWNLOADMANAGER_DESC, IDS_DOWNLOADMANAGER_ICON, false, true );
  268. RegisterForWiaEvents( NULL, CLSID_AcquisitionManager, GUID_ScanImage, IDS_DOWNLOADMANAGER_NAME, IDS_DOWNLOADMANAGER_DESC, IDS_DOWNLOADMANAGER_ICON, false, true );
  269. bRun = FALSE;
  270. break;
  271. }
  272. if (CSimpleString(lpszToken).CompareNoCase(_T("UnregServer"))==0)
  273. {
  274. _Module.UpdateRegistryFromResource(IDR_ACQUISITIONMANAGER, FALSE);
  275. _Module.UpdateRegistryFromResource(IDR_MINIMALTRANSFER,FALSE);
  276. nRet = _Module.UnregisterServer(TRUE);
  277. RegisterForWiaEvents( NULL, CLSID_AcquisitionManager, WIA_EVENT_DEVICE_CONNECTED, IDS_DOWNLOADMANAGER_NAME, IDS_DOWNLOADMANAGER_DESC, IDS_DOWNLOADMANAGER_ICON, false, false );
  278. RegisterForWiaEvents( NULL, CLSID_AcquisitionManager, GUID_ScanImage, IDS_DOWNLOADMANAGER_NAME, IDS_DOWNLOADMANAGER_DESC, IDS_DOWNLOADMANAGER_ICON, false, false );
  279. bRun = FALSE;
  280. break;
  281. }
  282. if (CSimpleString(lpszToken).ToUpper().Left(12)==CSimpleString(TEXT("SELECTDEVICE")))
  283. {
  284. bRunWizard = TRUE;
  285. bRun = FALSE;
  286. break;
  287. }
  288. if (CSimpleString(lpszToken).ToUpper().Left(10)==CSimpleString(TEXT("REGCONNECT")))
  289. {
  290. lpszToken = FindOneOf(lpszToken, TEXT(" "));
  291. WIA_TRACE((TEXT("Handling RegConnect for %s"), lpszToken ));
  292. hRes = RegisterForWiaEvents( CSimpleStringConvert::WideString(CSimpleString(lpszToken)), CLSID_MinimalTransfer, WIA_EVENT_DEVICE_CONNECTED, IDS_MINIMALTRANSFER_NAME, IDS_MINIMALTRANSFER_DESC, IDS_MINIMALTRANSFER_ICON, true, true );
  293. bRun = FALSE;
  294. break;
  295. }
  296. if (CSimpleString(lpszToken).ToUpper().Left(12)==CSimpleString(TEXT("UNREGCONNECT")))
  297. {
  298. lpszToken = FindOneOf(lpszToken, TEXT(" "));
  299. WIA_TRACE((TEXT("Handling RegUnconnect for %s"), lpszToken ));
  300. hRes = RegisterForWiaEvents( CSimpleStringConvert::WideString(CSimpleString(lpszToken)), CLSID_MinimalTransfer, WIA_EVENT_DEVICE_CONNECTED, IDS_MINIMALTRANSFER_NAME, IDS_MINIMALTRANSFER_DESC, IDS_MINIMALTRANSFER_ICON, false, false );
  301. bRun = FALSE;
  302. break;
  303. }
  304. lpszToken = FindOneOf(lpszToken, szTokens);
  305. }
  306. //
  307. // if /SelectDevice was specified, or no arguments were specified, we want to start the wizard
  308. //
  309. if (bRunWizard || !nSwitchCount)
  310. {
  311. //
  312. // Spawn the wizard
  313. //
  314. HRESULT hr = RunWiaWizard::RunWizard( NULL, NULL, TEXT("WiaWizardSingleInstanceDeviceSelection") );
  315. if (FAILED(hr))
  316. {
  317. //
  318. // Default error message
  319. //
  320. CSimpleString strMessage = CSimpleString( IDS_NO_DEVICE_TEXT, g_hInstance );
  321. int nIconId = MB_ICONHAND;
  322. switch (hr)
  323. {
  324. case HRESULT_FROM_WIN32(ERROR_SERVICE_DISABLED):
  325. //
  326. // Handle the situation where the service is disabled
  327. //
  328. strMessage = WiaUiUtil::GetErrorTextFromHResult(HRESULT_FROM_WIN32(ERROR_SERVICE_DISABLED));
  329. nIconId = MB_ICONHAND;
  330. break;
  331. }
  332. MessageBox( NULL, strMessage, CSimpleString( IDS_ERROR_TITLE, g_hInstance ), MB_ICONHAND );
  333. }
  334. }
  335. //
  336. // Otherwise run embedded
  337. //
  338. else if (bRun)
  339. {
  340. _Module.StartMonitor();
  341. #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
  342. hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
  343. _ASSERTE(SUCCEEDED(hRes));
  344. hRes = CoResumeClassObjects();
  345. #else
  346. hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE);
  347. #endif
  348. _ASSERTE(SUCCEEDED(hRes));
  349. MSG msg;
  350. while (GetMessage(&msg, 0, 0, 0))
  351. DispatchMessage(&msg);
  352. _Module.RevokeClassObjects();
  353. }
  354. _Module.Term();
  355. CoUninitialize();
  356. }
  357. //
  358. // Uninitialize fusion
  359. //
  360. SHFusionUninitialize();
  361. WIA_REPORT_LEAKS();
  362. WIA_DEBUG_DESTROY();
  363. return nRet;
  364. }
  365. #endif // DBG_GENERATE_PRETEND_EVENT