Source code of Windows XP (NT5)
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.

519 lines
15 KiB

  1. /****************************************************************************
  2. FILE: oactests.cxx
  3. ****************************************************************************/
  4. #include <windows.h>
  5. #include <oleext.h>
  6. #include <stdio.h>
  7. #include "oactest.h" // header file generated by MIDL compiler
  8. HRESULT RegisterClassFactory();
  9. HRESULT RevokeClassFactory();
  10. //Prototypes for local functions
  11. HRESULT RegisterLocalServer(REFCLSID rclsid);
  12. HRESULT RegisterProxyDll(const char *pszProxyDll);
  13. HRESULT UnregisterLocalServer(REFCLSID rclsid);
  14. HRESULT UnregisterProxyDll(const char *pszProxyDll);
  15. extern "C" const CLSID CLSID_COAccessControlTest
  16. = {0x20692b00,0xe710,0x11cf,{0xaf,0x0b,0x00,0xaa,0x00,0x44,0xfb,0x89}};
  17. extern ULONG g_ulFrequency;
  18. long g_LockCount = 0;
  19. long g_ObjectCount = 0;
  20. DWORD g_dwThreadID;
  21. ULONG g_ulFrequency;
  22. //+---------------------------------------------------------------------------
  23. //
  24. // Function: DecrementLockCount
  25. //
  26. // Synopsis: Decrements the lock count. The lock count controls the
  27. // registration of the class factory in the class table.
  28. // DecrementLockCount revokes the class factory when the
  29. // lock count is zero.
  30. //
  31. // Called By: ~CAccessControlTest, IClassFactory::LockServer(FALSE).
  32. //
  33. // See Also: ObjectCreated, ObjectDestroyed, IncrementLockCount.
  34. //
  35. //----------------------------------------------------------------------------
  36. void DecrementLockCount()
  37. {
  38. //Decrement the lock count.
  39. if(InterlockedDecrement(&g_LockCount) == 0)
  40. {
  41. //When the lock count is decremented to zero,
  42. //revoke the class factory.
  43. RevokeClassFactory();
  44. }
  45. }
  46. //+---------------------------------------------------------------------------
  47. //
  48. // Function: IncrementLockCount
  49. //
  50. // Synopsis: Increments the lock count. The lock count controls the
  51. // registration of the class factory in the class table.
  52. // If necessary, IncrementLockCount will reregister the class
  53. // factory in the class table.
  54. //
  55. // Called By: CAccessControlTest, IClassFactory::LockServer(TRUE).
  56. //
  57. // See Also: DecrementLockCount, ObjectCreated, ObjectDestroyed.
  58. //
  59. //----------------------------------------------------------------------------
  60. void IncrementLockCount()
  61. {
  62. if(g_LockCount == 0)
  63. {
  64. //Increment the lock count.
  65. InterlockedIncrement(&g_LockCount);
  66. //Reregister the class factory if necessary.
  67. RegisterClassFactory();
  68. }
  69. else
  70. {
  71. //Increment the lock count.
  72. InterlockedIncrement(&g_LockCount);
  73. }
  74. }
  75. //+---------------------------------------------------------------------------
  76. //
  77. // Function: main
  78. //
  79. // Synopsis: Main entry point for the server application. This function
  80. // initializes the server and processes the message loop.
  81. //
  82. //----------------------------------------------------------------------------
  83. int _cdecl main(int argc, char *argv[])
  84. {
  85. HRESULT hr = S_OK;
  86. int i;
  87. BOOL fRegisterServer = FALSE;
  88. BOOL fUnregisterServer = FALSE;
  89. BOOL fEmbedding = FALSE;
  90. BOOL fHelp = FALSE;
  91. MSG msg;
  92. // Parse each item, skip the command name
  93. for (i = 1; i < argc; i++)
  94. {
  95. if (lstrcmpiA( argv[i], "-Embedding" ) == 0)
  96. {
  97. //This server has been activated by OLE.
  98. fEmbedding = TRUE;
  99. }
  100. else if (lstrcmpiA( argv[i], "/REGSERVER" ) == 0)
  101. {
  102. fRegisterServer = TRUE;
  103. }
  104. else if (lstrcmpiA( argv[i], "/UNREGSERVER" ) == 0)
  105. {
  106. fUnregisterServer = TRUE;
  107. }
  108. else
  109. {
  110. fHelp = TRUE;
  111. }
  112. }
  113. if(fHelp == TRUE)
  114. {
  115. printf("USAGE: server /REGSERVER - Installs server in the registry.\n");
  116. printf(" server /UNREGSERVER - Removes server from the registry.\n");
  117. printf(" server -Embedding - Server was auto-started by OLE.\n");
  118. return 0;
  119. }
  120. else if(fUnregisterServer == TRUE)
  121. {
  122. hr = UnregisterLocalServer(CLSID_COAccessControlTest);
  123. if(FAILED(hr))
  124. {
  125. printf("Failed to remove local server from the registry.\n");
  126. }
  127. hr = UnregisterProxyDll("oactest.dll");
  128. if(FAILED(hr))
  129. {
  130. printf("Failed to remove proxy DLL from the registry.\n");
  131. }
  132. return 0;
  133. }
  134. //Install the local server in the registry.
  135. hr = RegisterLocalServer(CLSID_COAccessControlTest);
  136. if(FAILED(hr))
  137. {
  138. printf("Failed to install local server in the registry.\n");
  139. }
  140. //Install the proxy DLL in the registry.
  141. hr = RegisterProxyDll("oactest.dll");
  142. if(FAILED(hr))
  143. {
  144. printf("Failed to install proxy DLL in the registry.\n");
  145. }
  146. if(fRegisterServer == TRUE)
  147. return 0;
  148. //
  149. // Initialize OLE before calling any other OLE functions.
  150. //
  151. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  152. if(SUCCEEDED(hr))
  153. {
  154. hr = RegisterClassFactory();
  155. if(SUCCEEDED(hr))
  156. {
  157. LARGE_INTEGER liFreq;
  158. QueryPerformanceFrequency(&liFreq);
  159. g_ulFrequency = liFreq.LowPart;
  160. printf("Waiting for client to connect...\n");
  161. g_dwThreadID = GetCurrentThreadId();
  162. // Main message loop. We will remain in the message loop
  163. // until we get a WM_QUIT message.
  164. while (GetMessage(&msg, NULL, 0, 0))
  165. {
  166. TranslateMessage(&msg);
  167. DispatchMessage(&msg);
  168. }
  169. //If the class factory is still registered in the
  170. //class table, revoke it before we shut down.
  171. RevokeClassFactory();
  172. }
  173. else
  174. {
  175. printf("Failed to register class factory.\n");
  176. }
  177. CoUninitialize();
  178. }
  179. else
  180. {
  181. printf("CoInitialize failed.\n");
  182. }
  183. return 0;
  184. }
  185. //+---------------------------------------------------------------------------
  186. //
  187. // Function: ObjectCreated
  188. //
  189. // Synopsis: Increments the object count controlling the main message loop
  190. // of the server process.
  191. //
  192. // Called By: CAccessControlTest, CAccessControlTestFactory.
  193. //
  194. // See Also: DecrementLockCount, IncrementLockCount, ObjectDestroyed.
  195. //
  196. //----------------------------------------------------------------------------
  197. void ObjectCreated()
  198. {
  199. InterlockedIncrement(&g_ObjectCount);
  200. }
  201. //+---------------------------------------------------------------------------
  202. //
  203. // Function: ObjectDestroyed
  204. //
  205. // Synopsis: Decrements the object count controlling the main message loop
  206. // of the server process. When the object count is decremented
  207. // to zero, we post a WM_QUIT message. The main message loop will
  208. // exit and terminate the server process.
  209. //
  210. // Called By: ~CAccessControlTest, ~CAccessControlTestFactory.
  211. //
  212. // See Also: DecrementLockCount, IncrementLockCount, ObjectCreated.
  213. //
  214. //----------------------------------------------------------------------------
  215. void ObjectDestroyed()
  216. {
  217. if(InterlockedDecrement(&g_ObjectCount) == 0)
  218. {
  219. //When the last object is released, post a quit message.
  220. PostThreadMessage(g_dwThreadID, WM_QUIT, NULL, NULL);
  221. }
  222. }
  223. //+---------------------------------------------------------------------------
  224. //
  225. // Function: RegisterLocalServer
  226. //
  227. // Synopsis: Creates a registry key for a local server.
  228. //
  229. // Parameters: rclsid - Supplies the class ID of the local server.
  230. //
  231. //----------------------------------------------------------------------------
  232. HRESULT RegisterLocalServer(REFCLSID rclsid)
  233. {
  234. HRESULT hr;
  235. LONG error;
  236. HKEY hKeyCLSID; // key for ...\Classes\CLSID
  237. HKEY hKeyClassID;
  238. HKEY hKey; // current key
  239. DWORD dwDisposition;
  240. char szServer[MAX_PATH];
  241. char szClassID[39];
  242. unsigned long length;
  243. length = GetModuleFileNameA(0, szServer, sizeof(szServer));
  244. if(length == 0)
  245. {
  246. hr = HRESULT_FROM_WIN32(GetLastError());
  247. return hr;
  248. }
  249. //create the CLSID key
  250. error = RegCreateKeyExA(
  251. HKEY_CLASSES_ROOT,
  252. "CLSID",
  253. 0,
  254. "REG_SZ",
  255. REG_OPTION_NON_VOLATILE,
  256. KEY_ALL_ACCESS,
  257. 0,
  258. &hKeyCLSID,
  259. &dwDisposition);
  260. if(!error)
  261. {
  262. //convert the class ID to a registry key name.
  263. sprintf(szClassID, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  264. rclsid.Data1, rclsid.Data2, rclsid.Data3,
  265. rclsid.Data4[0], rclsid.Data4[1],
  266. rclsid.Data4[2], rclsid.Data4[3],
  267. rclsid.Data4[4], rclsid.Data4[5],
  268. rclsid.Data4[6], rclsid.Data4[7]);
  269. //create key for the server class
  270. error = RegCreateKeyExA(hKeyCLSID,
  271. szClassID,
  272. 0,
  273. "REG_SZ",
  274. REG_OPTION_NON_VOLATILE,
  275. KEY_ALL_ACCESS,
  276. 0,
  277. &hKeyClassID,
  278. &dwDisposition);
  279. if(!error)
  280. {
  281. //create LocalServer32 key.
  282. error = RegCreateKeyExA(hKeyClassID,
  283. "LocalServer32",
  284. 0,
  285. "REG_SZ",
  286. REG_OPTION_NON_VOLATILE,
  287. KEY_ALL_ACCESS,
  288. 0,
  289. &hKey,
  290. &dwDisposition);
  291. if(!error)
  292. {
  293. //Set the server name.
  294. error = RegSetValueExA(hKey,
  295. "",
  296. 0,
  297. REG_SZ,
  298. (const unsigned char *)szServer,
  299. lstrlenA(szServer) + 1);
  300. // Specifies in the registry that this
  301. // server supports both threading models
  302. error = RegSetValueExA( hKey
  303. , "ThreadingModel"
  304. , 0
  305. , REG_SZ
  306. , (const unsigned char *)"Both"
  307. , lstrlenA("Both") + 1);
  308. RegFlushKey(hKey);
  309. RegCloseKey(hKey);
  310. }
  311. RegCloseKey(hKeyClassID);
  312. }
  313. RegCloseKey(hKeyCLSID);
  314. }
  315. if(!error)
  316. hr = S_OK;
  317. else
  318. hr = HRESULT_FROM_WIN32(error);
  319. return hr;
  320. }
  321. //+---------------------------------------------------------------------------
  322. //
  323. // Function: RegisterProxyDll
  324. //
  325. // Synopsis: Creates registry entries for the interfaces contained in a
  326. // proxy DLL.
  327. //
  328. // Parameters: pszProxyDll - Supplies the filename of the proxy DLL.
  329. //
  330. // Notes: RegisterProxyDll calls the DllRegisterServer function
  331. // exported from the proxy DLL.
  332. //
  333. //----------------------------------------------------------------------------
  334. HRESULT RegisterProxyDll(const char *pszProxyDll)
  335. {
  336. HRESULT hr;
  337. HINSTANCE hProxyDll;
  338. HRESULT (STDAPICALLTYPE *pfnDllRegisterServer)();
  339. hProxyDll = LoadLibraryA(pszProxyDll);
  340. if(hProxyDll != 0)
  341. {
  342. pfnDllRegisterServer = (HRESULT (STDAPICALLTYPE *)())
  343. GetProcAddress(hProxyDll, "DllRegisterServer");
  344. if(pfnDllRegisterServer != 0)
  345. hr = (*pfnDllRegisterServer)();
  346. else
  347. hr = HRESULT_FROM_WIN32(GetLastError());
  348. FreeLibrary(hProxyDll);
  349. }
  350. else
  351. {
  352. hr = HRESULT_FROM_WIN32(GetLastError());
  353. }
  354. return hr;
  355. }
  356. //+---------------------------------------------------------------------------
  357. //
  358. // Function: UnregisterLocalServer
  359. //
  360. // Synopsis: Removes the registry key for a local server.
  361. //
  362. // Parameters: rclsid - Supplies the class ID of the local server.
  363. //
  364. //----------------------------------------------------------------------------
  365. HRESULT UnregisterLocalServer(REFCLSID rclsid)
  366. {
  367. HRESULT hr;
  368. HKEY hKeyCLSID;
  369. HKEY hKeyClassID;
  370. long error;
  371. char szClassID[39];
  372. //open the CLSID key
  373. error = RegOpenKeyExA(
  374. HKEY_CLASSES_ROOT,
  375. "CLSID",
  376. 0,
  377. KEY_ALL_ACCESS,
  378. &hKeyCLSID);
  379. if(!error)
  380. {
  381. //convert the class ID to a registry key name.
  382. sprintf(szClassID, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  383. rclsid.Data1, rclsid.Data2, rclsid.Data3,
  384. rclsid.Data4[0], rclsid.Data4[1],
  385. rclsid.Data4[2], rclsid.Data4[3],
  386. rclsid.Data4[4], rclsid.Data4[5],
  387. rclsid.Data4[6], rclsid.Data4[7]);
  388. //open registry key for class ID string
  389. error = RegOpenKeyExA(
  390. hKeyCLSID,
  391. szClassID,
  392. 0,
  393. KEY_ALL_ACCESS,
  394. &hKeyClassID);
  395. if(!error)
  396. {
  397. //delete LocalServer32 key.
  398. error = RegDeleteKeyA(hKeyClassID, "LocalServer32");
  399. RegCloseKey(hKeyClassID);
  400. }
  401. error = RegDeleteKeyA(hKeyCLSID, szClassID);
  402. RegCloseKey(hKeyCLSID);
  403. }
  404. if(!error)
  405. hr = S_OK;
  406. else
  407. hr = HRESULT_FROM_WIN32(error);
  408. return hr;
  409. }
  410. //+---------------------------------------------------------------------------
  411. //
  412. // Function: UnregisterProxyDll
  413. //
  414. // Synopsis: Removes registry entries for the interfaces contained in a
  415. // proxy DLL.
  416. //
  417. // Parameters: pszProxyDll - Supplies the filename of the proxy DLL.
  418. //
  419. // Notes: UnregisterProxyDll calls the DllUnregisterServer function
  420. // exported from the proxy DLL.
  421. //
  422. //----------------------------------------------------------------------------
  423. HRESULT UnregisterProxyDll(const char *pszProxyDll)
  424. {
  425. HRESULT hr;
  426. HINSTANCE hProxyDll;
  427. HRESULT (STDAPICALLTYPE *pfnDllUnregisterServer)();
  428. hProxyDll = LoadLibraryA(pszProxyDll);
  429. if(hProxyDll != 0)
  430. {
  431. pfnDllUnregisterServer = (HRESULT (STDAPICALLTYPE *)())
  432. GetProcAddress(hProxyDll, "DllUnregisterServer");
  433. if(pfnDllUnregisterServer != 0)
  434. hr = (*pfnDllUnregisterServer)();
  435. else
  436. hr = HRESULT_FROM_WIN32(GetLastError());
  437. FreeLibrary(hProxyDll);
  438. }
  439. else
  440. {
  441. hr = HRESULT_FROM_WIN32(GetLastError());
  442. }
  443. return hr;
  444. }
  445. /* end file actestss.c */