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.

480 lines
12 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1994-1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: helpcli.c
  6. * Content: client code to talk to dplaysvr.exe
  7. * allows multiple dplay winscock clients to share
  8. * a single port. see %manroot%\dplay\dplaysvr\dphelp.c
  9. * History:
  10. * Date By Reason
  11. * ==== == ======
  12. * 2/15/97 andyco created from w95help.h
  13. *
  14. ***************************************************************************/
  15. #include "helpcli.h"
  16. extern DWORD dwHelperPid;
  17. //**********************************************************************
  18. // Globals
  19. //**********************************************************************
  20. BOOL g_fDaclInited = FALSE;
  21. SECURITY_ATTRIBUTES g_sa;
  22. BYTE g_abSD[SECURITY_DESCRIPTOR_MIN_LENGTH];
  23. PSECURITY_ATTRIBUTES g_psa = NULL;
  24. PACL g_pEveryoneACL = NULL;
  25. //**********************************************************************
  26. // ------------------------------
  27. // DNGetNullDacl - Get a SECURITY_ATTRIBUTE structure that specifies a
  28. // NULL DACL which is accessible by all users.
  29. // Taken from IDirectPlay8 code base.
  30. //
  31. // Entry: Nothing
  32. //
  33. // Exit: PSECURITY_ATTRIBUTES
  34. // ------------------------------
  35. #undef DPF_MODNAME
  36. #define DPF_MODNAME "DNGetNullDacl"
  37. PSECURITY_ATTRIBUTES DNGetNullDacl()
  38. {
  39. PSID psidEveryone = NULL;
  40. SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
  41. DWORD dwAclSize;
  42. // This is done to make this function independent of DNOSIndirectionInit so that the debug
  43. // layer can call it before the indirection layer is initialized.
  44. if (!g_fDaclInited)
  45. {
  46. if (!InitializeSecurityDescriptor((SECURITY_DESCRIPTOR*)g_abSD, SECURITY_DESCRIPTOR_REVISION))
  47. {
  48. DPF(0, "Failed to initialize security descriptor" );
  49. goto Error;
  50. }
  51. // Create SID for the Everyone group.
  52. if (!AllocateAndInitializeSid(&siaWorld, 1, SECURITY_WORLD_RID, 0,
  53. 0, 0, 0, 0, 0, 0, &psidEveryone))
  54. {
  55. DPF(0, "Failed to allocate Everyone SID" );
  56. goto Error;
  57. }
  58. dwAclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidEveryone) - sizeof(DWORD);
  59. // Allocate the ACL, this won't be a tracked allocation and we will let process cleanup destroy it
  60. g_pEveryoneACL = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
  61. if (g_pEveryoneACL == NULL)
  62. {
  63. DPF(0, "Failed to allocate ACL buffer" );
  64. goto Error;
  65. }
  66. // Intialize the ACL.
  67. if (!InitializeAcl(g_pEveryoneACL, dwAclSize, ACL_REVISION))
  68. {
  69. DPF(0, "Failed to initialize ACL" );
  70. goto Error;
  71. }
  72. // Add the ACE.
  73. if (!AddAccessAllowedAce(g_pEveryoneACL, ACL_REVISION, GENERIC_ALL, psidEveryone))
  74. {
  75. DPF(0, "Failed to add ACE to ACL" );
  76. goto Error;
  77. }
  78. // We no longer need the SID that was allocated.
  79. FreeSid(psidEveryone);
  80. psidEveryone = NULL;
  81. // Add the ACL to the security descriptor..
  82. if (!SetSecurityDescriptorDacl((SECURITY_DESCRIPTOR*)g_abSD, TRUE, g_pEveryoneACL, FALSE))
  83. {
  84. DPF(0, "Failed to add ACL to security descriptor" );
  85. goto Error;
  86. }
  87. g_sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  88. g_sa.lpSecurityDescriptor = g_abSD;
  89. g_sa.bInheritHandle = FALSE;
  90. g_psa = &g_sa;
  91. g_fDaclInited = TRUE;
  92. }
  93. Error:
  94. if (psidEveryone)
  95. {
  96. FreeSid(psidEveryone);
  97. psidEveryone = NULL;
  98. }
  99. return g_psa;
  100. }
  101. //**********************************************************************
  102. /*
  103. * sendRequest
  104. *
  105. * communicate a request to DPHELP
  106. */
  107. static BOOL sendRequest( LPDPHELPDATA req_phd )
  108. {
  109. OSVERSIONINFOA VersionInfo;
  110. BOOL fUseGlobalNamespace;
  111. LPDPHELPDATA phd;
  112. HANDLE hmem;
  113. HANDLE hmutex;
  114. HANDLE hackevent;
  115. HANDLE hstartevent;
  116. BOOL rc;
  117. // Determine if we're running on NT.
  118. memset(&VersionInfo, 0, sizeof(VersionInfo));
  119. VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
  120. if (GetVersionExA(&VersionInfo))
  121. {
  122. if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  123. {
  124. DPF(2, "Running on NT version %u.%u.%u, using global namespace.",
  125. VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, VersionInfo.dwBuildNumber);
  126. fUseGlobalNamespace = TRUE;
  127. }
  128. else
  129. {
  130. DPF(2, "Running on 9x version %u.%u.%u, not using global namespace.",
  131. VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, LOWORD(VersionInfo.dwBuildNumber));
  132. fUseGlobalNamespace = FALSE;
  133. }
  134. }
  135. else
  136. {
  137. DPF(0, "Could not determine OS version, assuming global namespace not needed.");
  138. fUseGlobalNamespace = FALSE;
  139. }
  140. /*
  141. * get events start/ack events
  142. */
  143. if (fUseGlobalNamespace)
  144. {
  145. hstartevent = CreateEvent( DNGetNullDacl(), FALSE, FALSE, "Global\\" DPHELP_EVENT_NAME );
  146. }
  147. else
  148. {
  149. hstartevent = CreateEvent( NULL, FALSE, FALSE, DPHELP_EVENT_NAME );
  150. }
  151. if( hstartevent == NULL )
  152. {
  153. return FALSE;
  154. }
  155. if (fUseGlobalNamespace)
  156. {
  157. hackevent = CreateEvent( DNGetNullDacl(), FALSE, FALSE, "Global\\" DPHELP_ACK_EVENT_NAME );
  158. }
  159. else
  160. {
  161. hackevent = CreateEvent( NULL, FALSE, FALSE, DPHELP_ACK_EVENT_NAME );
  162. }
  163. if( hackevent == NULL )
  164. {
  165. CloseHandle( hstartevent );
  166. return FALSE;
  167. }
  168. /*
  169. * create shared memory area
  170. */
  171. if (fUseGlobalNamespace)
  172. {
  173. hmem = CreateFileMapping( INVALID_HANDLE_VALUE, DNGetNullDacl(),
  174. PAGE_READWRITE, 0, sizeof( DPHELPDATA ),
  175. "Global\\" DPHELP_SHARED_NAME );
  176. }
  177. else
  178. {
  179. hmem = CreateFileMapping( INVALID_HANDLE_VALUE, NULL,
  180. PAGE_READWRITE, 0, sizeof( DPHELPDATA ),
  181. DPHELP_SHARED_NAME );
  182. }
  183. if( hmem == NULL )
  184. {
  185. DPF( 1, "Could not create file mapping!" );
  186. CloseHandle( hstartevent );
  187. CloseHandle( hackevent );
  188. return FALSE;
  189. }
  190. phd = (LPDPHELPDATA) MapViewOfFile( hmem, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
  191. if( phd == NULL )
  192. {
  193. DPF( 1, "Could not create view of file!" );
  194. CloseHandle( hmem );
  195. CloseHandle( hstartevent );
  196. CloseHandle( hackevent );
  197. return FALSE;
  198. }
  199. /*
  200. * wait for access to the shared memory
  201. */
  202. if (fUseGlobalNamespace)
  203. {
  204. hmutex = OpenMutex( SYNCHRONIZE, FALSE, "Global\\" DPHELP_MUTEX_NAME );
  205. }
  206. else
  207. {
  208. hmutex = OpenMutex( SYNCHRONIZE, FALSE, DPHELP_MUTEX_NAME );
  209. }
  210. if( hmutex == NULL )
  211. {
  212. DPF( 1, "Could not create mutex!" );
  213. UnmapViewOfFile( phd );
  214. CloseHandle( hmem );
  215. CloseHandle( hstartevent );
  216. CloseHandle( hackevent );
  217. return FALSE;
  218. }
  219. WaitForSingleObject( hmutex, INFINITE );
  220. /*
  221. * wake up DPHELP with our request
  222. */
  223. memcpy( phd, req_phd, sizeof( DPHELPDATA ) );
  224. if( SetEvent( hstartevent ) )
  225. {
  226. WaitForSingleObject( hackevent, INFINITE );
  227. memcpy( req_phd, phd, sizeof( DPHELPDATA ) );
  228. rc = TRUE;
  229. }
  230. else
  231. {
  232. DPF( 1, "Could not signal event to notify DPHELP!" );
  233. rc = FALSE;
  234. }
  235. /*
  236. * done with things
  237. */
  238. ReleaseMutex( hmutex );
  239. CloseHandle( hmutex );
  240. CloseHandle( hstartevent );
  241. CloseHandle( hackevent );
  242. UnmapViewOfFile( phd );
  243. CloseHandle( hmem );
  244. return rc;
  245. } /* sendRequest */
  246. /*
  247. * HelpcliFini
  248. *
  249. * Free resources allocated to talk to DPlaySvr.
  250. */
  251. void HelpcliFini(void)
  252. {
  253. if (g_pEveryoneACL)
  254. {
  255. HeapFree(GetProcessHeap(), 0, g_pEveryoneACL);
  256. g_pEveryoneACL = NULL;
  257. }
  258. g_psa = NULL;
  259. g_fDaclInited = FALSE;
  260. } /* HelpcliFini */
  261. /*
  262. * WaitForHelperStartup
  263. */
  264. BOOL WaitForHelperStartup( void )
  265. {
  266. OSVERSIONINFOA VersionInfo;
  267. BOOL fUseGlobalNamespace;
  268. HANDLE hevent;
  269. DWORD rc;
  270. // Determine if we're running on NT.
  271. memset(&VersionInfo, 0, sizeof(VersionInfo));
  272. VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
  273. if (GetVersionExA(&VersionInfo))
  274. {
  275. if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  276. {
  277. DPF(2, "Running on NT version %u.%u.%u, using global namespace.",
  278. VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, VersionInfo.dwBuildNumber);
  279. fUseGlobalNamespace = TRUE;
  280. }
  281. else
  282. {
  283. DPF(2, "Running on 9x version %u.%u.%u, not using global namespace.",
  284. VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, LOWORD(VersionInfo.dwBuildNumber));
  285. fUseGlobalNamespace = FALSE;
  286. }
  287. }
  288. else
  289. {
  290. rc = GetLastError();
  291. DPF(0, "Could not determine OS version (err = %u), assuming global namespace not needed.", rc);
  292. fUseGlobalNamespace = FALSE;
  293. }
  294. if (fUseGlobalNamespace)
  295. {
  296. hevent = CreateEvent( DNGetNullDacl(), TRUE, FALSE, "Global\\" DPHELP_STARTUP_EVENT_NAME );
  297. }
  298. else
  299. {
  300. hevent = CreateEvent( NULL, TRUE, FALSE, DPHELP_STARTUP_EVENT_NAME );
  301. }
  302. if( hevent == NULL )
  303. {
  304. return FALSE;
  305. }
  306. DPF( 3, "Wait DPHELP startup event to be triggered" );
  307. rc = WaitForSingleObject( hevent, INFINITE );
  308. CloseHandle( hevent );
  309. return TRUE;
  310. } /* WaitForHelperStartup */
  311. /*
  312. * CreateHelperProcess
  313. */
  314. BOOL CreateHelperProcess( LPDWORD ppid )
  315. {
  316. OSVERSIONINFOA VersionInfo;
  317. BOOL fUseGlobalNamespace;
  318. DWORD rc;
  319. STARTUPINFO si;
  320. PROCESS_INFORMATION pi;
  321. HANDLE h;
  322. char szDPlaySvrPath[MAX_PATH + sizeof("\\dplaysvr.exe") + 1];
  323. char szDPlaySvr[sizeof("dplaysvr.exe")] = "dplaysvr.exe";
  324. // Determine if we're running on NT.
  325. memset(&VersionInfo, 0, sizeof(VersionInfo));
  326. VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
  327. if (GetVersionExA(&VersionInfo))
  328. {
  329. if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  330. {
  331. //DPF(2, "Running on NT version %u.%u.%u, using global namespace.",
  332. // VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, VersionInfo.dwBuildNumber);
  333. fUseGlobalNamespace = TRUE;
  334. }
  335. else
  336. {
  337. //DPF(2, "Running on 9x version %u.%u.%u, not using global namespace.",
  338. // VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, LOWORD(VersionInfo.dwBuildNumber));
  339. fUseGlobalNamespace = FALSE;
  340. }
  341. }
  342. else
  343. {
  344. rc = GetLastError();
  345. DPF(0, "Could not determine OS version (err = %u), assuming global namespace not needed.", rc);
  346. fUseGlobalNamespace = FALSE;
  347. }
  348. if( dwHelperPid == 0 )
  349. {
  350. if (fUseGlobalNamespace)
  351. {
  352. h = OpenEvent( SYNCHRONIZE, FALSE, "Global\\" DPHELP_STARTUP_EVENT_NAME );
  353. }
  354. else
  355. {
  356. h = OpenEvent( SYNCHRONIZE, FALSE, DPHELP_STARTUP_EVENT_NAME );
  357. }
  358. if( h == NULL )
  359. {
  360. // Get Windows system directory name
  361. if (GetSystemDirectory(szDPlaySvrPath, (MAX_PATH + 1)) == 0)
  362. {
  363. DPF( 0, "Could not get system directory" );
  364. return FALSE;
  365. }
  366. strcat(szDPlaySvrPath, "\\dplaysvr.exe");
  367. si.cb = sizeof(STARTUPINFO);
  368. si.lpReserved = NULL;
  369. si.lpDesktop = NULL;
  370. si.lpTitle = NULL;
  371. si.dwFlags = 0;
  372. si.cbReserved2 = 0;
  373. si.lpReserved2 = NULL;
  374. DPF( 3, "Creating helper process dplaysvr.exe now" );
  375. if( !CreateProcess(szDPlaySvrPath, szDPlaySvr, NULL, NULL, FALSE,
  376. NORMAL_PRIORITY_CLASS,
  377. NULL, NULL, &si, &pi) )
  378. {
  379. DPF( 2, "Could not create dplaysvr.exe" );
  380. return FALSE;
  381. }
  382. dwHelperPid = pi.dwProcessId;
  383. DPF( 3, "Helper Process created" );
  384. }
  385. else
  386. {
  387. DPHELPDATA hd;
  388. memset(&hd,0,sizeof(DPHELPDATA)); // make prefix happy.
  389. DPF( 3, "dplaysvr already exists, waiting for dplaysvr event" );
  390. WaitForSingleObject( h, INFINITE );
  391. CloseHandle( h );
  392. DPF( 3, "Asking for DPHELP pid" );
  393. hd.req = DPHELPREQ_RETURNHELPERPID;
  394. sendRequest( &hd );
  395. dwHelperPid = hd.pid;
  396. DPF( 3, "DPHELP pid = %08lx", dwHelperPid );
  397. }
  398. *ppid = dwHelperPid;
  399. return TRUE;
  400. }
  401. *ppid = dwHelperPid;
  402. return FALSE;
  403. } /* CreateHelperProcess */
  404. // notify dphelp.c that we have a new server on this system
  405. HRESULT HelperAddDPlayServer(USHORT port)
  406. {
  407. DPHELPDATA hd;
  408. DWORD pid = GetCurrentProcessId();
  409. memset(&hd, 0, sizeof(DPHELPDATA));
  410. hd.req = DPHELPREQ_DPLAYADDSERVER;
  411. hd.pid = pid;
  412. hd.port = port;
  413. if (sendRequest(&hd)) return hd.hr;
  414. else return E_FAIL;
  415. } // HelperAddDPlayServer
  416. // server is going away
  417. BOOL HelperDeleteDPlayServer(USHORT port)
  418. {
  419. DPHELPDATA hd;
  420. DWORD pid = GetCurrentProcessId();
  421. memset(&hd, 0, sizeof(DPHELPDATA));
  422. hd.req = DPHELPREQ_DPLAYDELETESERVER;
  423. hd.pid = pid;
  424. hd.port = port;
  425. return sendRequest(&hd);
  426. } // HelperDeleteDPlayServer