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.

935 lines
22 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: enumsvr.cpp
  6. * Content: DirectPlay8 <--> DPNSVR Utility functions
  7. *
  8. *@@BEGIN_MSINTERNAL
  9. * History:
  10. * Date By Reason
  11. * ==== == ======
  12. * 03/24/00 rmt Created
  13. * 03/25/00 rmt Updated to handle new status/table format for n providers
  14. * 09/04/00 mjn Changed DPNSVR_Register() and DPNSVR_UnRegister() to use guids directly (rather than ApplicationDesc)
  15. *@@END_MSINTERNAL
  16. *
  17. ***************************************************************************/
  18. #include "dnsvlibi.h"
  19. #undef DPF_SUBCOMP
  20. #define DPF_SUBCOMP DN_SUBCOMP_DPNSVR
  21. #define DPNSVR_WAIT_STARTUP 30000
  22. #undef DPF_MODNAME
  23. #define DPF_MODNAME "DPNSVR_IsRunning"
  24. BOOL DPNSVR_IsRunning()
  25. {
  26. DNHANDLE hRunningHandle = NULL;
  27. //
  28. // Check to see if running by opening the running event
  29. //
  30. hRunningHandle = DNOpenEvent( SYNCHRONIZE, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_RUNNING );
  31. if( hRunningHandle != NULL )
  32. {
  33. DNCloseHandle(hRunningHandle);
  34. return( TRUE );
  35. }
  36. return( FALSE );
  37. }
  38. #undef DPF_MODNAME
  39. #define DPF_MODNAME "DPNSVR_WaitForStartup"
  40. HRESULT DPNSVR_WaitForStartup( DNHANDLE hWaitHandle )
  41. {
  42. HRESULT hr;
  43. LONG lWaitResult;
  44. DPFX(DPFPREP,4,"Parameters: (none)" );
  45. //
  46. // Wait for startup.. just in case it's starting up.
  47. //
  48. if ((lWaitResult = DNWaitForSingleObject( hWaitHandle,DPNSVR_WAIT_STARTUP )) == WAIT_TIMEOUT)
  49. {
  50. DPFX(DPFPREP,5,"Timed out waiting for DPNSVR to startup" );
  51. hr = DPNERR_TIMEDOUT;
  52. }
  53. else
  54. {
  55. DPFX(DPFPREP,5,"DPNSVR has started up" );
  56. hr = DPN_OK;
  57. }
  58. DPFX(DPFPREP,4,"Returning: [0x%lx]",hr );
  59. return( hr );
  60. }
  61. #undef DPF_MODNAME
  62. #define DPF_MODNAME "DPNSVR_SendMessage"
  63. HRESULT DPNSVR_SendMessage( void *pvMessage, DWORD dwSize )
  64. {
  65. HRESULT hr;
  66. CDPNSVRIPCQueue ipcQueue;
  67. DPFX(DPFPREP,4,"Parameters: pvMessage [0x%p],dwSize [%ld]",pvMessage,dwSize);
  68. if ((hr = ipcQueue.Open( &GUID_DPNSVR_QUEUE,DPNSVR_MSGQ_SIZE,DPNSVR_MSGQ_OPEN_FLAG_NO_CREATE )) == DPN_OK)
  69. {
  70. if ((hr = ipcQueue.Send(static_cast<BYTE*>(pvMessage),
  71. dwSize,
  72. DPNSVR_TIMEOUT_REQUEST,
  73. DPNSVR_MSGQ_MSGFLAGS_USER1,
  74. 0 )) != DPN_OK)
  75. {
  76. DPFX(DPFPREP,5,"Send failed to DPNSVR request queue");
  77. }
  78. ipcQueue.Close();
  79. }
  80. else
  81. {
  82. DPFX(DPFPREP,5,"Could not open DPNSVR request queue");
  83. }
  84. DPFX(DPFPREP,4,"Returning: [0x%lx]",hr );
  85. return( hr );
  86. }
  87. #undef DPF_MODNAME
  88. #define DPF_MODNAME "DPNSVR_WaitForResult"
  89. HRESULT DPNSVR_WaitForResult( CDPNSVRIPCQueue *pQueue )
  90. {
  91. HRESULT hr;
  92. BYTE *pBuffer = NULL;
  93. DWORD dwBufferSize = 0;
  94. DPNSVR_MSGQ_HEADER MsgHeader;
  95. DPNSVR_MSG_RESULT *pMsgResult;
  96. DPFX(DPFPREP,4,"Parameters: pQueue [0x%p]",pQueue);
  97. DNASSERT( pQueue != NULL );
  98. if( DNWaitForSingleObject( pQueue->GetReceiveSemaphoreHandle(),DPNSVR_TIMEOUT_RESULT ) == WAIT_TIMEOUT )
  99. {
  100. DPFX(DPFPREP,5,"Wait for response timed out" );
  101. hr = DPNERR_TIMEDOUT;
  102. goto Failure;
  103. }
  104. while((hr = pQueue->GetNextMessage( &MsgHeader,pBuffer,&dwBufferSize )) == DPNERR_BUFFERTOOSMALL )
  105. {
  106. if (pBuffer)
  107. {
  108. delete [] pBuffer;
  109. pBuffer = NULL;
  110. }
  111. pBuffer = new BYTE[dwBufferSize];
  112. if( pBuffer==NULL )
  113. {
  114. hr = DPNERR_OUTOFMEMORY;
  115. goto Failure;
  116. }
  117. }
  118. if (hr != DPN_OK)
  119. {
  120. goto Failure;
  121. }
  122. if (pBuffer == NULL)
  123. {
  124. DPFERR( "Getting message failed" );
  125. hr = DPNERR_GENERIC;
  126. goto Failure;
  127. }
  128. pMsgResult = reinterpret_cast<DPNSVR_MSG_RESULT*>(pBuffer);
  129. if( pMsgResult->dwType != DPNSVR_MSGID_RESULT )
  130. {
  131. DPFERR( "Invalid message from DPNSVR" );
  132. DPFX(DPFPREP,5,"Recieved [0x%lx]",pMsgResult->dwType );
  133. hr = DPNERR_GENERIC;
  134. goto Failure;
  135. }
  136. hr = pMsgResult->hrCommandResult;
  137. Exit:
  138. if( pBuffer )
  139. {
  140. delete [] pBuffer;
  141. pBuffer = NULL;
  142. }
  143. DPFX(DPFPREP,4,"Returning: [0x%lx]",hr );
  144. return( hr );
  145. Failure:
  146. goto Exit;
  147. }
  148. #undef DPF_MODNAME
  149. #define DPF_MODNAME "DPNSVR_StartDPNSVR"
  150. HRESULT DPNSVR_StartDPNSVR( void )
  151. {
  152. HRESULT hr;
  153. DNHANDLE hRunningEvent = NULL;
  154. DNHANDLE hStartupEvent = NULL;
  155. DNPROCESS_INFORMATION pi;
  156. #if !defined(WINCE) || defined(WINCE_ON_DESKTOP)
  157. TCHAR szSystemDir[MAX_PATH+1];
  158. DWORD dwSystemDirLen;
  159. TCHAR *pszApplicationName = NULL;
  160. DWORD dwApplicationNameLen;
  161. STARTUPINFO si;
  162. #endif //!WINCE
  163. #if defined(WINCE) && !defined(WINCE_ON_DESKTOP)
  164. TCHAR szDPNSVR[] = _T("dpnsvr.exe");
  165. #else
  166. // CreateProcess will attempt to add a terminating NULL so this must be writeable
  167. #if !defined(DBG) || !defined( DIRECTX_REDIST )
  168. TCHAR szDPNSVR[] = _T("\"dpnsvr.exe\"");
  169. #else
  170. // For redist debug builds we append a 'd' to the name to allow both debug and retail to be installed on the system
  171. TCHAR szDPNSVR[] = _T("\"dpnsvrd.exe\"");
  172. #endif // !defined(DBG) || !defined( DIRECTX_REDIST )
  173. #endif
  174. DPFX(DPFPREP,4,"Parameters: (none)");
  175. #if !defined(WINCE) || defined(WINCE_ON_DESKTOP)
  176. //
  177. // Get Windows system directory name
  178. //
  179. if ((dwSystemDirLen = GetSystemDirectory(szSystemDir,MAX_PATH+1)) == 0)
  180. {
  181. DPFERR("Could not get system directory");
  182. hr = DPNERR_GENERIC;
  183. goto Failure;
  184. }
  185. //
  186. // Create application name for CreateProcess
  187. //
  188. dwApplicationNameLen = dwSystemDirLen + (1 + _tcslen(_T("dpnsvrd.exe")) + 1); // slash and NULL terminator
  189. if ((pszApplicationName = static_cast<TCHAR*>(DNMalloc(dwApplicationNameLen * sizeof(TCHAR)))) == NULL)
  190. {
  191. DPFERR("Could not allocate space for application name");
  192. hr = DPNERR_OUTOFMEMORY;
  193. goto Failure;
  194. }
  195. pszApplicationName[0] = _T('\0');
  196. _tcscat(pszApplicationName,szSystemDir);
  197. _tcscat(pszApplicationName,_T("\\"));
  198. #if !defined(DBG) || !defined( DIRECTX_REDIST )
  199. _tcscat(pszApplicationName,_T("dpnsvr.exe"));
  200. #else
  201. //
  202. // For redist debug builds we append a 'd' to the name to allow both debug and retail to be installed on the system
  203. //
  204. _tcscat(pszApplicationName,_T("dpnsvrd.exe"));
  205. #endif // !defined(DBG) || !defined( DIRECTX_REDIST )
  206. #endif //!WINCE
  207. //
  208. // Create startup event which we will wait on once we launch DPNSVR
  209. //
  210. if ((hStartupEvent = DNCreateEvent( DNGetNullDacl(),TRUE,FALSE,GLOBALIZE_STR STRING_GUID_DPNSVR_STARTUP )) == NULL)
  211. {
  212. DPFERR("Could not create DPNSVR startup event");
  213. hr = DPNERR_OUTOFMEMORY;
  214. goto Failure;
  215. }
  216. //
  217. // Attempt to open the running event
  218. //
  219. if ((hRunningEvent = DNOpenEvent( SYNCHRONIZE, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_RUNNING )) != NULL)
  220. {
  221. DPFX(DPFPREP,5,"DPNSVR is already running");
  222. hr = DPNSVR_WaitForStartup(hStartupEvent);
  223. goto Failure;
  224. }
  225. #if !defined(WINCE) || defined(WINCE_ON_DESKTOP)
  226. memset(&si,0x00,sizeof(STARTUPINFO));
  227. si.cb = sizeof(STARTUPINFO);
  228. #endif // !WINCE
  229. DPFX(DPFPREP,5,"Launching DPNSVR" );
  230. #if defined(WINCE) && !defined(WINCE_ON_DESKTOP)
  231. //
  232. // WinCE AV's on a NULL first param and requires that Environment and CurrentDirectory be NULL.
  233. // It also ignores STARTUPINFO.
  234. //
  235. if( !DNCreateProcess(szDPNSVR, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, NULL, &pi) )
  236. #else // !WINCE
  237. if( !DNCreateProcess(pszApplicationName, szDPNSVR, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi) )
  238. #endif // WINCE
  239. {
  240. DPFERR("CreateProcess() failed!");
  241. DPFX(DPFPREP,5,"Error = [0x%lx]",GetLastError());
  242. hr = DPNERR_GENERIC;
  243. goto Failure;
  244. }
  245. DNCloseHandle( pi.hProcess );
  246. DNCloseHandle( pi.hThread );
  247. DPFX(DPFPREP,5,"DPNSVR started" );
  248. hr = DPNSVR_WaitForStartup(hStartupEvent);
  249. Exit:
  250. if ( hRunningEvent != NULL )
  251. {
  252. DNCloseHandle( hRunningEvent );
  253. hRunningEvent = NULL;
  254. }
  255. if ( hStartupEvent != NULL )
  256. {
  257. DNCloseHandle( hStartupEvent );
  258. hStartupEvent = NULL;
  259. }
  260. #if !defined(WINCE) || defined(WINCE_ON_DESKTOP)
  261. if (pszApplicationName)
  262. {
  263. DNFree(pszApplicationName);
  264. pszApplicationName = NULL;
  265. }
  266. #endif // !WINCE
  267. DPFX(DPFPREP,4,"Returning: [0x%lx]",hr );
  268. return( hr );
  269. Failure:
  270. goto Exit;
  271. }
  272. // DPNSVR_Register
  273. //
  274. // This function asks the DPNSVR process to add the application specified to it's list of applications and forward
  275. // enumeration requests from the main port to the specified addresses.
  276. //
  277. // If the DPNSVR process is not running, it will be started by this function.
  278. //
  279. #undef DPF_MODNAME
  280. #define DPF_MODNAME "DPNSVR_Register"
  281. HRESULT DPNSVR_Register(const GUID *const pguidApplication,
  282. const GUID *const pguidInstance,
  283. IDirectPlay8Address *const pAddress)
  284. {
  285. HRESULT hr;
  286. BOOL fQueueOpen = FALSE;
  287. BYTE *pSendBuffer = NULL;
  288. DWORD dwSendBufferSize = 0;
  289. DWORD dwURLSize = 0;
  290. GUID guidSP;
  291. CDPNSVRIPCQueue appQueue;
  292. DPNSVR_MSG_OPENPORT *pMsgOpen;
  293. DPFX(DPFPREP,2,"Parameters: pguidApplication [0x%p],pguidInstance [0x%p],pAddress [0x%p]",
  294. pguidApplication,pguidInstance,pAddress);
  295. DNASSERT( pguidApplication != NULL );
  296. DNASSERT( pguidInstance != NULL );
  297. DNASSERT( pAddress != NULL );
  298. //
  299. // Get SP and URL size from address
  300. //
  301. if ((hr = IDirectPlay8Address_GetSP( pAddress,&guidSP )) != DPN_OK)
  302. {
  303. DPFERR("Could not get SP from address");
  304. DisplayDNError(0,hr);
  305. goto Failure;
  306. }
  307. if ((hr = IDirectPlay8Address_GetURLA( pAddress,reinterpret_cast<char*>(pSendBuffer),&dwURLSize )) != DPNERR_BUFFERTOOSMALL)
  308. {
  309. DPFERR("Could not get URL from address");
  310. DisplayDNError(0,hr);
  311. goto Failure;
  312. }
  313. dwSendBufferSize = sizeof( DPNSVR_MSG_OPENPORT ) + dwURLSize;
  314. //
  315. // Create message buffer
  316. //
  317. pSendBuffer = new BYTE[dwSendBufferSize];
  318. if( pSendBuffer == NULL )
  319. {
  320. DPFERR("Could not allocate send buffer");
  321. hr = DPNERR_OUTOFMEMORY;
  322. goto Failure;
  323. }
  324. //
  325. // Attempt to launch DPNSVR if it has not yet been launched
  326. //
  327. if ((hr = DPNSVR_StartDPNSVR()) != DPN_OK)
  328. {
  329. DPFERR("Could not start DPNSVR");
  330. DisplayDNError(0,hr);
  331. goto Failure;
  332. }
  333. //
  334. // Open queue
  335. //
  336. if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK)
  337. {
  338. DPFERR("Could not open DPNSVR request queue");
  339. DisplayDNError(0,hr);
  340. goto Failure;
  341. }
  342. fQueueOpen = TRUE;
  343. //
  344. // Create open port message
  345. pMsgOpen = (DPNSVR_MSG_OPENPORT*) pSendBuffer;
  346. pMsgOpen->Header.dwType = DPNSVR_MSGID_OPENPORT;
  347. pMsgOpen->Header.guidInstance = *pguidInstance;
  348. pMsgOpen->dwProcessID = GetCurrentProcessId();
  349. pMsgOpen->guidApplication = *pguidApplication;
  350. pMsgOpen->guidSP = guidSP;
  351. pMsgOpen->dwAddressSize = dwURLSize;
  352. if ((hr = IDirectPlay8Address_GetURLA( pAddress,(char *)&pMsgOpen[1],&dwURLSize )) != DPN_OK)
  353. {
  354. DPFERR("Could not get URL from address");
  355. DisplayDNError(0,hr);
  356. goto Failure;
  357. }
  358. //
  359. // Send request to DPNSVR
  360. //
  361. if ((hr = DPNSVR_SendMessage( pSendBuffer,dwSendBufferSize )) != DPN_OK)
  362. {
  363. DPFERR("Could not send message to DPNSVR");
  364. DisplayDNError(0,hr);
  365. goto Failure;
  366. }
  367. //
  368. // Wait for DPNSVR to respond
  369. //
  370. if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK)
  371. {
  372. DPFERR("Could not get response from DPNSVR");
  373. DisplayDNError(0,hr);
  374. goto Failure;
  375. }
  376. Exit:
  377. if( pSendBuffer != NULL )
  378. {
  379. delete [] pSendBuffer;
  380. pSendBuffer = NULL;
  381. }
  382. if (fQueueOpen)
  383. {
  384. appQueue.Close();
  385. fQueueOpen = FALSE;
  386. }
  387. DPFX(DPFPREP,2,"Returning: [0x%lx]",hr);
  388. return( hr );
  389. Failure:
  390. goto Exit;
  391. }
  392. #undef DPF_MODNAME
  393. #define DPF_MODNAME "DPNSVR_UnRegister"
  394. HRESULT DPNSVR_UnRegister(const GUID *const pguidApplication,const GUID *const pguidInstance)
  395. {
  396. HRESULT hr;
  397. BOOL fQueueOpen = FALSE;
  398. CDPNSVRIPCQueue appQueue;
  399. DPNSVR_MSG_CLOSEPORT MsgClose;
  400. DPFX(DPFPREP,2,"Parameters: pguidApplication [0x%p],pguidInstance [0x%p]",pguidApplication,pguidInstance);
  401. DNASSERT( pguidApplication != NULL );
  402. DNASSERT( pguidInstance != NULL );
  403. //
  404. // Ensure DPNSVR is running
  405. //
  406. if( !DPNSVR_IsRunning() )
  407. {
  408. DPFX(DPFPREP,3,"DPNSVR is not running" );
  409. hr = DPNERR_INVALIDAPPLICATION;
  410. goto Failure;
  411. }
  412. //
  413. // Open DPNSVR request queue
  414. //
  415. if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK)
  416. {
  417. DPFERR("Could not open DPNSVR queue");
  418. DisplayDNError(0,hr);
  419. goto Failure;
  420. }
  421. fQueueOpen = TRUE;
  422. //
  423. // Create close port message
  424. //
  425. MsgClose.Header.dwType = DPNSVR_MSGID_CLOSEPORT;
  426. MsgClose.Header.guidInstance = *pguidInstance;
  427. MsgClose.dwProcessID = GetCurrentProcessId();
  428. MsgClose.guidApplication = *pguidApplication;
  429. //
  430. // Send message to DPNSVR
  431. //
  432. if ((hr = DPNSVR_SendMessage( &MsgClose,sizeof(DPNSVR_MSG_CLOSEPORT) )) != DPN_OK)
  433. {
  434. DPFERR("Could not send message to DPNSVR");
  435. DisplayDNError(0,hr);
  436. goto Failure;
  437. }
  438. //
  439. // Wait for DPNSVR to respond
  440. //
  441. if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK)
  442. {
  443. DPFERR("Could not get response from DPNSVR");
  444. DisplayDNError(0,hr);
  445. goto Failure;
  446. }
  447. Exit:
  448. if (fQueueOpen)
  449. {
  450. appQueue.Close();
  451. fQueueOpen = FALSE;
  452. }
  453. DPFX(DPFPREP,2,"Returning: [0x%lx]",hr);
  454. return( hr );
  455. Failure:
  456. goto Exit;
  457. }
  458. #undef DPF_MODNAME
  459. #define DPF_MODNAME "DPNSVR_RequestTerminate"
  460. HRESULT DPNSVR_RequestTerminate( const GUID *pguidInstance )
  461. {
  462. HRESULT hr;
  463. BOOL fQueueOpen = FALSE;
  464. CDPNSVRIPCQueue appQueue;
  465. DPNSVR_MSG_COMMAND MsgCommand;
  466. DPFX(DPFPREP,2,"Parameters: pguidInstance [0x%p]",pguidInstance);
  467. DNASSERT( pguidInstance != NULL );
  468. //
  469. // Ensure DPNSVR is running
  470. //
  471. if( !DPNSVR_IsRunning() )
  472. {
  473. DPFX(DPFPREP,3,"DPNSVR is not running" );
  474. hr = DPNERR_INVALIDAPPLICATION;
  475. goto Failure;
  476. }
  477. //
  478. // Open DPNSVR request queue
  479. //
  480. if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK)
  481. {
  482. DPFERR("Could not open DPNSVR queue");
  483. DisplayDNError(0,hr);
  484. goto Failure;
  485. }
  486. fQueueOpen = TRUE;
  487. //
  488. // Create terminate message
  489. //
  490. MsgCommand.Header.dwType = DPNSVR_MSGID_COMMAND;
  491. MsgCommand.Header.guidInstance = *pguidInstance;
  492. MsgCommand.dwCommand = DPNSVR_COMMAND_KILL;
  493. MsgCommand.dwParam1 = 0;
  494. MsgCommand.dwParam2 = 0;
  495. //
  496. // Send message to DPNSVR
  497. //
  498. if ((hr = DPNSVR_SendMessage( &MsgCommand,sizeof(DPNSVR_MSG_COMMAND) )) != DPN_OK)
  499. {
  500. DPFERR("Could not send message to DPNSVR");
  501. DisplayDNError(0,hr);
  502. goto Failure;
  503. }
  504. //
  505. // Wait for DPNSVR to respond
  506. //
  507. if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK)
  508. {
  509. DPFERR("Could not get response from DPNSVR");
  510. DisplayDNError(0,hr);
  511. goto Failure;
  512. }
  513. Exit:
  514. if (fQueueOpen)
  515. {
  516. appQueue.Close();
  517. fQueueOpen = FALSE;
  518. }
  519. DPFX(DPFPREP,2,"Returning: [0x%lx]",hr);
  520. return hr;
  521. Failure:
  522. goto Exit;
  523. }
  524. #undef DPF_MODNAME
  525. #define DPF_MODNAME "DPNSVR_RequestStatus"
  526. HRESULT DPNSVR_RequestStatus( const GUID *pguidInstance,PSTATUSHANDLER pStatusHandler,PVOID pvContext )
  527. {
  528. HRESULT hr;
  529. CDPNSVRIPCQueue appQueue;
  530. DPNSVR_MSG_COMMAND dpnCommand;
  531. DNHANDLE hStatusMutex = NULL;
  532. DNHANDLE hStatusSharedMemory = NULL;
  533. void *pServerStatus = NULL;
  534. DWORD dwSize;
  535. BOOL fOpened = FALSE;
  536. BOOL fHaveMutex = FALSE;
  537. //
  538. // Ensure DPNSVR is running
  539. //
  540. if( !DPNSVR_IsRunning() )
  541. {
  542. DPFERR( "DPNSVR is not running" );
  543. hr = DPNERR_INVALIDAPPLICATION;
  544. goto Failure;
  545. }
  546. //
  547. // Open DPNSVR request queue
  548. //
  549. if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK)
  550. {
  551. DPFERR( "Failed to open DPNSVR request queue" );
  552. DisplayDNError( 0,hr );
  553. goto Failure;
  554. }
  555. fOpened = TRUE;
  556. //
  557. // Create request
  558. //
  559. dpnCommand.Header.dwType = DPNSVR_MSGID_COMMAND;
  560. dpnCommand.Header.guidInstance = *pguidInstance;
  561. dpnCommand.dwCommand = DPNSVR_COMMAND_STATUS;
  562. dpnCommand.dwParam1 = 0;
  563. dpnCommand.dwParam2 = 0;
  564. //
  565. // Send command request to DPNSVR
  566. //
  567. if ((hr = DPNSVR_SendMessage( &dpnCommand,sizeof(DPNSVR_MSG_COMMAND) )) != DPN_OK)
  568. {
  569. DPFERR( "Failed to send command to DPNSVR request queue" );
  570. DisplayDNError( 0,hr );
  571. goto Failure;
  572. }
  573. //
  574. // Wait for DPNSVR to respond
  575. //
  576. if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK)
  577. {
  578. DPFERR( "Failed to receive response from DPNSVR" );
  579. DisplayDNError( 0,hr );
  580. goto Failure;
  581. }
  582. #ifdef WINNT
  583. hStatusMutex = DNOpenMutex( SYNCHRONIZE, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_STATUSSTORAGE );
  584. #else
  585. hStatusMutex = DNOpenMutex( MUTEX_ALL_ACCESS, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_STATUSSTORAGE );
  586. #endif // WINNT
  587. if( hStatusMutex == NULL )
  588. {
  589. DPFERR( "Server exited before table was retrieved" );
  590. hr = DPNERR_INVALIDAPPLICATION;
  591. goto Failure;
  592. }
  593. //
  594. // Get mutex for shared memory
  595. //
  596. DNWaitForSingleObject( hStatusMutex, INFINITE );
  597. fHaveMutex = TRUE;
  598. //
  599. // Map shared memory
  600. //
  601. if ((hStatusSharedMemory = DNOpenFileMapping(FILE_MAP_READ,FALSE,STRING_GUID_DPNSVR_STATUS_MEMORY)) == NULL)
  602. {
  603. hr = GetLastError();
  604. DPFERR( "Unable to open file mapping" );
  605. DisplayDNError( 0,hr );
  606. goto Failure;
  607. }
  608. if ((pServerStatus = MapViewOfFile( HANDLE_FROM_DNHANDLE(hStatusSharedMemory),
  609. FILE_MAP_READ,
  610. 0,
  611. 0,
  612. sizeof(DPNSVR_STATUSHEADER)) ) == NULL)
  613. {
  614. hr = GetLastError();
  615. DPFERR( "Unable to map view of file" );
  616. DisplayDNError( 0,hr );
  617. goto Failure;
  618. }
  619. dwSize = sizeof(DPNSVR_STATUSHEADER) + (static_cast<DPNSVR_STATUSHEADER*>(pServerStatus)->dwSPCount * sizeof(DPNSVR_SPSTATUS));
  620. UnmapViewOfFile( pServerStatus );
  621. pServerStatus = NULL;
  622. if ((pServerStatus = MapViewOfFile( HANDLE_FROM_DNHANDLE(hStatusSharedMemory),
  623. FILE_MAP_READ,
  624. 0,
  625. 0,
  626. dwSize) ) == NULL)
  627. {
  628. hr = GetLastError();
  629. DPFERR( "Unable to re-map view of file" );
  630. DisplayDNError( 0,hr );
  631. goto Failure;
  632. }
  633. (*pStatusHandler)(pServerStatus,pvContext);
  634. DNReleaseMutex( hStatusMutex );
  635. fHaveMutex = FALSE;
  636. hr = DPN_OK;
  637. Exit:
  638. if ( hStatusMutex )
  639. {
  640. if ( fHaveMutex )
  641. {
  642. DNReleaseMutex( hStatusMutex );
  643. fHaveMutex = FALSE;
  644. }
  645. DNCloseHandle( hStatusMutex );
  646. hStatusMutex = NULL;
  647. }
  648. if ( fOpened )
  649. {
  650. appQueue.Close();
  651. fOpened = FALSE;
  652. }
  653. if( pServerStatus )
  654. {
  655. UnmapViewOfFile(pServerStatus);
  656. pServerStatus = NULL;
  657. }
  658. if( hStatusSharedMemory )
  659. {
  660. DNCloseHandle(hStatusSharedMemory);
  661. hStatusSharedMemory = NULL;
  662. }
  663. return( hr );
  664. Failure:
  665. goto Exit;
  666. }
  667. #undef DPF_MODNAME
  668. #define DPF_MODNAME "DPNSVR_RequestTable"
  669. HRESULT DPNSVR_RequestTable( const GUID *pguidInstance,PTABLEHANDLER pTableHandler,PVOID pvContext )
  670. {
  671. HRESULT hr;
  672. CDPNSVRIPCQueue appQueue;
  673. DPNSVR_MSG_COMMAND dpnCommand;
  674. DNHANDLE hTableMutex = NULL;
  675. DNHANDLE hSharedMemory = NULL;
  676. void *pServerTable = NULL;
  677. DWORD dwSize;
  678. BOOL fOpened = FALSE;
  679. BOOL fHaveMutex = FALSE;
  680. //
  681. // Ensure DPNSVR is running
  682. //
  683. if( !DPNSVR_IsRunning() )
  684. {
  685. DPFERR( "DPNSVR is not running" );
  686. hr = DPNERR_INVALIDAPPLICATION;
  687. goto Failure;
  688. }
  689. //
  690. // Open DPNSVR request queue
  691. //
  692. if ((hr = appQueue.Open( pguidInstance,DPNSVR_MSGQ_SIZE,0 )) != DPN_OK)
  693. {
  694. DPFERR( "Failed to open DPNSVR request queue" );
  695. DisplayDNError( 0,hr );
  696. goto Failure;
  697. }
  698. fOpened = TRUE;
  699. //
  700. // Create request
  701. //
  702. dpnCommand.Header.dwType = DPNSVR_MSGID_COMMAND;
  703. dpnCommand.Header.guidInstance = *pguidInstance;
  704. dpnCommand.dwCommand = DPNSVR_COMMAND_TABLE;
  705. dpnCommand.dwParam1 = 0;
  706. dpnCommand.dwParam2 = 0;
  707. //
  708. // Send command request to DPNSVR
  709. //
  710. if ((hr = DPNSVR_SendMessage( &dpnCommand,sizeof(DPNSVR_MSG_COMMAND) )) != DPN_OK)
  711. {
  712. DPFERR( "Failed to send command to DPNSVR request queue" );
  713. DisplayDNError( 0,hr );
  714. goto Failure;
  715. }
  716. //
  717. // Wait for DPNSVR to respond
  718. //
  719. if ((hr = DPNSVR_WaitForResult( &appQueue )) != DPN_OK)
  720. {
  721. DPFERR( "Failed to receive response from DPNSVR" );
  722. DisplayDNError( 0,hr );
  723. goto Failure;
  724. }
  725. #ifdef WINNT
  726. hTableMutex = DNOpenMutex( SYNCHRONIZE, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_TABLESTORAGE );
  727. #else
  728. hTableMutex = DNOpenMutex( MUTEX_ALL_ACCESS, FALSE, GLOBALIZE_STR STRING_GUID_DPNSVR_TABLESTORAGE );
  729. #endif // WINNT
  730. if( hTableMutex == NULL )
  731. {
  732. DPFERR( "Server exited before table was retrieved" );
  733. hr = DPNERR_INVALIDAPPLICATION;
  734. goto Failure;
  735. }
  736. //
  737. // Get mutex for shared memory
  738. //
  739. DNWaitForSingleObject( hTableMutex, INFINITE );
  740. fHaveMutex = TRUE;
  741. //
  742. // Map shared memory
  743. //
  744. if ((hSharedMemory = DNOpenFileMapping(FILE_MAP_READ,FALSE,STRING_GUID_DPNSVR_TABLE_MEMORY)) == NULL)
  745. {
  746. hr = GetLastError();
  747. DPFERR( "Unable to open file mapping" );
  748. DisplayDNError( 0,hr );
  749. goto Failure;
  750. }
  751. if ((pServerTable = MapViewOfFile( HANDLE_FROM_DNHANDLE(hSharedMemory),
  752. FILE_MAP_READ,
  753. 0,
  754. 0,
  755. sizeof(DPNSVR_TABLEHEADER)) ) == NULL)
  756. {
  757. hr = GetLastError();
  758. DPFERR( "Unable to map view of file" );
  759. DisplayDNError( 0,hr );
  760. goto Failure;
  761. }
  762. dwSize = static_cast<DPNSVR_TABLEHEADER*>(pServerTable)->dwTableSize;
  763. UnmapViewOfFile( pServerTable );
  764. pServerTable = NULL;
  765. if ((pServerTable = MapViewOfFile( HANDLE_FROM_DNHANDLE(hSharedMemory),
  766. FILE_MAP_READ,
  767. 0,
  768. 0,
  769. dwSize) ) == NULL)
  770. {
  771. hr = GetLastError();
  772. DPFERR( "Unable to re-map view of file" );
  773. DisplayDNError( 0,hr );
  774. goto Failure;
  775. }
  776. (*pTableHandler)(pServerTable,pvContext);
  777. DNReleaseMutex( hTableMutex );
  778. fHaveMutex = FALSE;
  779. hr = DPN_OK;
  780. Exit:
  781. if ( hTableMutex )
  782. {
  783. if ( fHaveMutex )
  784. {
  785. DNReleaseMutex( hTableMutex );
  786. fHaveMutex = FALSE;
  787. }
  788. DNCloseHandle( hTableMutex );
  789. hTableMutex = NULL;
  790. }
  791. if ( fOpened )
  792. {
  793. appQueue.Close();
  794. fOpened = FALSE;
  795. }
  796. if( pServerTable )
  797. {
  798. UnmapViewOfFile(pServerTable);
  799. pServerTable = NULL;
  800. }
  801. if( hSharedMemory )
  802. {
  803. DNCloseHandle(hSharedMemory);
  804. hSharedMemory = NULL;
  805. }
  806. return( hr );
  807. Failure:
  808. goto Exit;
  809. }