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.

906 lines
22 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995-1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dplaysvr.c
  6. * Content: dplay winsock shared .exe - allows multiple apps to share
  7. * a single winsock port
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 2/10/97 andyco created it from ddhelp
  12. * 29-jan-98 sohailm added support for stream enum sessions
  13. * 1/12/2000 aarono added support for rsip
  14. * 11/29/2000 aarono B#228292: prefix bug initialize path in WinMain()
  15. *
  16. ***************************************************************************/
  17. #ifdef WINNT
  18. #ifdef DBG
  19. #undef DEBUG
  20. #define DEBUG
  21. #endif
  22. #endif
  23. #include <windows.h>
  24. #include "dplaysvr.h"
  25. #include "newdpf.h"
  26. #include "memalloc.h"
  27. #include "dphelp.h"
  28. #if USE_RSIP
  29. #include "rsip.h"
  30. #elif USE_NATHELP
  31. #include "dpnathlp.h"
  32. #endif
  33. #if USE_RSIP
  34. BOOL bRsip;
  35. #endif
  36. #if USE_NATHELP
  37. extern BOOL natGetCapsUpdate(VOID);
  38. extern BOOL natInit(VOID);
  39. extern VOID natFini(VOID);
  40. extern HRESULT natRegisterUDPPort(DWORD port);
  41. extern IDirectPlayNATHelp *g_pINatHelp;
  42. #endif
  43. HANDLE hInstApp;
  44. BOOL bNoCallbacks;
  45. CRITICAL_SECTION gcsCritSection; // the crit section we take in winmain
  46. // this is a global so dphelp can take it before
  47. // forwarding enum requests that come in on its
  48. // receive thread (manbugs 3907)
  49. int gnCSCount; // dplaysvr lock count
  50. /*
  51. * Externs
  52. */
  53. extern RECEIVELIST gReceiveList;
  54. extern FDS gReadfds;
  55. // we watch every dplay process so when it exits we
  56. // make sure it cleaned up...
  57. typedef struct _PROCESSDATA
  58. {
  59. struct _PROCESSDATA *link;
  60. DWORD pid;
  61. } PROCESSDATA, *LPPROCESSDATA;
  62. LPPROCESSDATA lpProcessList; // list of all processes that are registered
  63. // with us
  64. //**********************************************************************
  65. // Globals
  66. //**********************************************************************
  67. BOOL g_fDaclInited = FALSE;
  68. SECURITY_ATTRIBUTES g_sa;
  69. BYTE g_abSD[SECURITY_DESCRIPTOR_MIN_LENGTH];
  70. PSECURITY_ATTRIBUTES g_psa = NULL;
  71. PACL g_pEveryoneACL = NULL;
  72. /*
  73. * ThreadProc
  74. *
  75. * Open a process and wait for it to terminate
  76. */
  77. DWORD WINAPI ThreadProc( LPVOID *pdata )
  78. {
  79. HANDLE hproc;
  80. DWORD rc;
  81. LPPROCESSDATA ppd;
  82. LPPROCESSDATA curr;
  83. LPPROCESSDATA prev;
  84. PROCESSDATA pd;
  85. DPHELPDATA hd;
  86. ppd = (LPPROCESSDATA) pdata;
  87. /*
  88. * get a handle to the process that attached to DDRAW
  89. */
  90. DPF( 2, "Watchdog thread started for pid %08lx", ppd->pid );
  91. hproc = OpenProcess( PROCESS_QUERY_INFORMATION | SYNCHRONIZE,
  92. FALSE, ppd->pid );
  93. if( hproc == NULL )
  94. {
  95. DPF( 1, "OpenProcess for %08lx failed!", ppd->pid );
  96. ExitThread( 0 );
  97. }
  98. /*
  99. * wait for process to die
  100. */
  101. rc = WaitForSingleObject( hproc, INFINITE );
  102. if( rc == WAIT_FAILED )
  103. {
  104. DPF( 1, "Wait for process %08lx failed", ppd->pid );
  105. CloseHandle( hproc );
  106. ExitThread( 0 );
  107. }
  108. /*
  109. * remove process from the list of watched processes
  110. */
  111. ENTER_DPLAYSVR();
  112. pd = *ppd;
  113. curr = lpProcessList;
  114. prev = NULL;
  115. while( curr != NULL )
  116. {
  117. if( curr == ppd )
  118. {
  119. if( prev == NULL )
  120. {
  121. lpProcessList = curr->link;
  122. }
  123. else
  124. {
  125. prev->link = curr->link;
  126. }
  127. DPF( 2, "PID %08lx removed from list", ppd->pid );
  128. MemFree( curr );
  129. break;
  130. }
  131. prev = curr;
  132. curr = curr->link;
  133. }
  134. if( bNoCallbacks )
  135. {
  136. DPF( 1, "No callbacks allowed: leaving thread early" );
  137. LEAVE_DPLAYSVR();
  138. CloseHandle( hproc );
  139. ExitThread( 0 );
  140. }
  141. // clean up!
  142. memset(&hd,0,sizeof(hd));
  143. hd.pid = pd.pid;
  144. DPlayHelp_DeleteServer(&hd,TRUE);
  145. LEAVE_DPLAYSVR();
  146. CloseHandle( hproc );
  147. ExitThread( 0 );
  148. return 0;
  149. } /* ThreadProc */
  150. /*
  151. * MainWndProc
  152. */
  153. LONG_PTR __stdcall MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  154. {
  155. switch(message)
  156. {
  157. case WM_ENDSESSION:
  158. /*
  159. * shoot ourselves in the head
  160. */
  161. if( lParam == FALSE )
  162. {
  163. DPF( 3, "WM_ENDSESSION" );
  164. ENTER_DPLAYSVR();
  165. DPF( 1, "Setting NO CALLBACKS" );
  166. bNoCallbacks = TRUE;
  167. LEAVE_DPLAYSVR();
  168. }
  169. else
  170. {
  171. DPF( 3, "User logging off" );
  172. }
  173. break;
  174. }
  175. return DefWindowProc(hWnd, message, wParam, lParam);
  176. } /* MainWndProc */
  177. /*
  178. * WindowThreadProc
  179. */
  180. void WindowThreadProc( LPVOID pdata )
  181. {
  182. static char szClassName[] = "DPlayHelpWndClass";
  183. WNDCLASS cls;
  184. MSG msg;
  185. HWND hwnd;
  186. /*
  187. * build class and create window
  188. */
  189. cls.lpszClassName = szClassName;
  190. cls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  191. cls.hInstance = hInstApp;
  192. cls.hIcon = NULL;
  193. cls.hCursor = NULL;
  194. cls.lpszMenuName = NULL;
  195. cls.style = 0;
  196. cls.lpfnWndProc = MainWndProc;
  197. cls.cbWndExtra = 0;
  198. cls.cbClsExtra = 0;
  199. if( !RegisterClass( &cls ) )
  200. {
  201. DPF( 1, "RegisterClass FAILED!" );
  202. ExitThread( 0 );
  203. }
  204. hwnd = CreateWindow( szClassName, szClassName,
  205. WS_POPUP, 0, 0, 0, 0, NULL, NULL, hInstApp, NULL);
  206. if( hwnd == NULL )
  207. {
  208. DPF( 1, "No monitor window!" );
  209. ExitThread( 0 );
  210. }
  211. /*
  212. * pump the messages
  213. */
  214. while( GetMessage( &msg, NULL, 0, 0 ) )
  215. {
  216. TranslateMessage( &msg );
  217. DispatchMessage( &msg );
  218. }
  219. DPF( 1, "Exiting WindowThreadProc" );
  220. ExitThread( 1 );
  221. } /* WindowThreadProc */
  222. //
  223. // called by by DPlayHelp_AddServer when we get a new process attached.
  224. // we wait for the process to go away, and then make sure it cleaned
  225. // all its registered servers up.
  226. //
  227. void WatchNewPid(LPDPHELPDATA phd)
  228. {
  229. LPPROCESSDATA ppd;
  230. BOOL found;
  231. DWORD tid;
  232. DPF( 1, "watching new pid" );
  233. ENTER_DPLAYSVR();
  234. ppd = lpProcessList;
  235. found = FALSE;
  236. while( ppd != NULL )
  237. {
  238. if( ppd->pid == phd->pid )
  239. {
  240. DPF( 2, "Have thread for process %08lx already", phd->pid );
  241. found = TRUE;
  242. break;
  243. }
  244. ppd = ppd->link;
  245. }
  246. /*
  247. * couldn't find anyone waiting on this process, so create
  248. * a brand spanking new thread
  249. */
  250. if( !found )
  251. {
  252. DPF( 2, "Allocating new thread for process %08lx",phd->pid );
  253. ppd = MemAlloc( sizeof( PROCESSDATA ) );
  254. if( ppd != NULL )
  255. {
  256. HANDLE h;
  257. ppd->link = lpProcessList;
  258. lpProcessList = ppd;
  259. ppd->pid = phd->pid;
  260. h = CreateThread(NULL,
  261. 0,
  262. (LPTHREAD_START_ROUTINE) ThreadProc,
  263. (LPVOID)ppd,
  264. 0,
  265. (LPDWORD)&tid);
  266. if( h != NULL )
  267. {
  268. DPF( 2, "Thread %08lx created",tid);
  269. CloseHandle( h );
  270. }
  271. else
  272. {
  273. #ifdef DEBUG
  274. DPF( 0, "COULD NOT CREATE HELPER THREAD FOR PID %08lx", phd->pid );
  275. DebugBreak(); //_asm int 3;
  276. #endif
  277. }
  278. }
  279. else
  280. {
  281. #ifdef DEBUG
  282. DPF( 0, "OUT OF MEMORY CREATING HELPER THREAD FOR PID %08lx", phd->pid );
  283. DebugBreak(); //_asm int 3;
  284. #endif
  285. }
  286. }
  287. LEAVE_DPLAYSVR();
  288. } // WatchNewPid
  289. typedef DWORD (WINAPI *PFNREGISTERSERVICE)(DWORD,DWORD);
  290. // nt's winbase.h doesn't have these constants - we need them
  291. // so we can compile. taken from \proj\dev\inc\winbase.h
  292. #ifndef RSP_UNREGISTER_SERVICE
  293. #define RSP_UNREGISTER_SERVICE 0x00000000
  294. #endif
  295. #ifndef RSP_SIMPLE_SERVICE
  296. #define RSP_SIMPLE_SERVICE 0x00000001
  297. #endif
  298. // on Win95, we want to call RegisterServiceProcess
  299. // but, it's not available on NT, so we can't import it directly
  300. // here we try to find it dynamically in kernel32. if we find it,
  301. // we call it, otherwise we assume we're on NT and it's not avaible
  302. void MakeMeService()
  303. {
  304. HANDLE hLib;
  305. PFNREGISTERSERVICE pfnRegisterServiceProcess;
  306. hLib = LoadLibrary("kernel32.dll");
  307. if (!hLib)
  308. {
  309. // wacky!
  310. DPF(1,"could not load library kernel32 to register service proc");
  311. return;
  312. }
  313. pfnRegisterServiceProcess = (PFNREGISTERSERVICE)GetProcAddress(hLib,"RegisterServiceProcess");
  314. if (!pfnRegisterServiceProcess)
  315. {
  316. // this is expected on NT
  317. DPF(3,"could not register service process - expected on NT");
  318. FreeLibrary(hLib);
  319. return ;
  320. }
  321. pfnRegisterServiceProcess( 0, RSP_SIMPLE_SERVICE );
  322. FreeLibrary(hLib);
  323. return ;
  324. } // MakeMeService
  325. // on Win95, we want to call RegisterServiceProcess to Unregister
  326. // (see MakeMeService)
  327. void StopServiceProcess()
  328. {
  329. HANDLE hLib;
  330. PFNREGISTERSERVICE pfnRegisterServiceProcess;
  331. hLib = LoadLibrary("kernel32.dll");
  332. if (!hLib)
  333. {
  334. // wacky!
  335. DPF(1,"could not load library kernel32 to register service proc");
  336. return;
  337. }
  338. pfnRegisterServiceProcess = (PFNREGISTERSERVICE)GetProcAddress(hLib,"RegisterServiceProcess");
  339. if (!pfnRegisterServiceProcess)
  340. {
  341. // this is expected on NT
  342. DPF(3,"could not unregister service process - not avail - not tragic");
  343. FreeLibrary(hLib);
  344. return ;
  345. }
  346. // unregistered!
  347. pfnRegisterServiceProcess( 0, RSP_UNREGISTER_SERVICE );
  348. FreeLibrary(hLib);
  349. return ;
  350. } // StopServiceProcess
  351. //**********************************************************************
  352. // ------------------------------
  353. // DNGetNullDacl - Get a SECURITY_ATTRIBUTE structure that specifies a
  354. // NULL DACL which is accessible by all users.
  355. // Taken from IDirectPlay8 code base.
  356. //
  357. // Entry: Nothing
  358. //
  359. // Exit: PSECURITY_ATTRIBUTES
  360. // ------------------------------
  361. #undef DPF_MODNAME
  362. #define DPF_MODNAME "DNGetNullDacl"
  363. PSECURITY_ATTRIBUTES DNGetNullDacl()
  364. {
  365. PSID psidEveryone = NULL;
  366. SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
  367. DWORD dwAclSize;
  368. // This is done to make this function independent of DNOSIndirectionInit so that the debug
  369. // layer can call it before the indirection layer is initialized.
  370. if (!g_fDaclInited)
  371. {
  372. if (!InitializeSecurityDescriptor((SECURITY_DESCRIPTOR*)g_abSD, SECURITY_DESCRIPTOR_REVISION))
  373. {
  374. DPF(0, "Failed to initialize security descriptor" );
  375. goto Error;
  376. }
  377. // Create SID for the Everyone group.
  378. if (!AllocateAndInitializeSid(&siaWorld, 1, SECURITY_WORLD_RID, 0,
  379. 0, 0, 0, 0, 0, 0, &psidEveryone))
  380. {
  381. DPF(0, "Failed to allocate Everyone SID" );
  382. goto Error;
  383. }
  384. dwAclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidEveryone) - sizeof(DWORD);
  385. // Allocate the ACL, this won't be a tracked allocation and we will let process cleanup destroy it
  386. g_pEveryoneACL = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
  387. if (g_pEveryoneACL == NULL)
  388. {
  389. DPF(0, "Failed to allocate ACL buffer" );
  390. goto Error;
  391. }
  392. // Intialize the ACL.
  393. if (!InitializeAcl(g_pEveryoneACL, dwAclSize, ACL_REVISION))
  394. {
  395. DPF(0, "Failed to initialize ACL" );
  396. goto Error;
  397. }
  398. // Add the ACE.
  399. if (!AddAccessAllowedAce(g_pEveryoneACL, ACL_REVISION, GENERIC_ALL, psidEveryone))
  400. {
  401. DPF(0, "Failed to add ACE to ACL" );
  402. goto Error;
  403. }
  404. // We no longer need the SID that was allocated.
  405. FreeSid(psidEveryone);
  406. psidEveryone = NULL;
  407. // Add the ACL to the security descriptor..
  408. if (!SetSecurityDescriptorDacl((SECURITY_DESCRIPTOR*)g_abSD, TRUE, g_pEveryoneACL, FALSE))
  409. {
  410. DPF(0, "Failed to add ACL to security descriptor" );
  411. goto Error;
  412. }
  413. g_sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  414. g_sa.lpSecurityDescriptor = g_abSD;
  415. g_sa.bInheritHandle = FALSE;
  416. g_psa = &g_sa;
  417. g_fDaclInited = TRUE;
  418. }
  419. Error:
  420. if (psidEveryone)
  421. {
  422. FreeSid(psidEveryone);
  423. psidEveryone = NULL;
  424. }
  425. return g_psa;
  426. }
  427. //**********************************************************************
  428. /*
  429. * WinMain
  430. */
  431. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  432. LPSTR lpCmdLine, int nCmdShow)
  433. {
  434. DWORD tid;
  435. DWORD rc;
  436. OSVERSIONINFOA VersionInfo;
  437. BOOL fUseGlobalNamespace;
  438. HANDLE hstartevent;
  439. HANDLE hstartupevent;
  440. HANDLE hmutex;
  441. HANDLE hackevent;
  442. LPDPHELPDATA phd;
  443. HANDLE hsharedmem;
  444. HANDLE h;
  445. char szSystemDir[MAX_PATH*sizeof(WCHAR)];
  446. DWORD tWait;
  447. #if (USE_RSIP || USE_NATHELP)
  448. DWORD tLast;
  449. DWORD tNow;
  450. #define RSIP_RENEW_TEST_INTERVAL 60000
  451. #endif
  452. DPFINIT();
  453. DPF( 2, "*** dplaysvr STARTED, PID=%08lx ***", GetCurrentProcessId() );
  454. if( !MemInit() )
  455. {
  456. DPF( 1, "Could not init memory manager" );
  457. return 0;
  458. }
  459. /*
  460. * Set our working directory to the system directory.
  461. * This prevents us from holding network connections open
  462. * forever if the first DirectDraw app that we run is across
  463. * a network connection.
  464. */
  465. memset(szSystemDir, 0, sizeof(WCHAR));
  466. GetSystemDirectory(szSystemDir, sizeof(szSystemDir));
  467. SetCurrentDirectory(szSystemDir);
  468. // Determine if we're running on NT.
  469. memset(&VersionInfo, 0, sizeof(VersionInfo));
  470. VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo);
  471. if (GetVersionExA(&VersionInfo))
  472. {
  473. if (VersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  474. {
  475. DPF(2, "Running on NT version %u.%u.%u, using global namespace.",
  476. VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, VersionInfo.dwBuildNumber);
  477. fUseGlobalNamespace = TRUE;
  478. }
  479. else
  480. {
  481. DPF(2, "Running on 9x version %u.%u.%u, not using global namespace.",
  482. VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, LOWORD(VersionInfo.dwBuildNumber));
  483. fUseGlobalNamespace = FALSE;
  484. }
  485. }
  486. else
  487. {
  488. rc = GetLastError();
  489. DPF(0, "Could not determine OS version (err = %u), assuming global namespace not needed.", rc);
  490. fUseGlobalNamespace = FALSE;
  491. }
  492. // try to register ourselves as a service so user can't see us
  493. // in task list
  494. MakeMeService();
  495. #if 0
  496. // andyco - not sure if we need this...
  497. /*
  498. * We must guarantee that DPHELP unloads after the last ddraw app,
  499. * since ctrl-alt-del may have happened while an app held the ddraw
  500. * lock, and DPHELP needs to clean up orphaned cheap ddraw mutex
  501. * locks.
  502. */
  503. if ( ! SetProcessShutdownParameters(0x100,SHUTDOWN_NORETRY) )
  504. {
  505. DPF(0,"dplaysvr could not set itself to shutdown last!");
  506. }
  507. #endif
  508. hInstApp = hInstance;
  509. /*
  510. * create startup event
  511. */
  512. if (fUseGlobalNamespace)
  513. {
  514. hstartupevent = CreateEvent( DNGetNullDacl(), TRUE, FALSE, "Global\\" DPHELP_STARTUP_EVENT_NAME );
  515. }
  516. else
  517. {
  518. hstartupevent = CreateEvent( NULL, TRUE, FALSE, DPHELP_STARTUP_EVENT_NAME );
  519. }
  520. if( hstartupevent == NULL )
  521. {
  522. DPF( 1, "Could not create startup event!" );
  523. return 0;
  524. }
  525. /*
  526. * create shared memory area
  527. */
  528. if (fUseGlobalNamespace)
  529. {
  530. hsharedmem = CreateFileMapping( INVALID_HANDLE_VALUE, DNGetNullDacl(),
  531. PAGE_READWRITE, 0, sizeof( DPHELPDATA ),
  532. "Global\\" DPHELP_SHARED_NAME );
  533. }
  534. else
  535. {
  536. hsharedmem = CreateFileMapping( INVALID_HANDLE_VALUE, NULL,
  537. PAGE_READWRITE, 0, sizeof( DPHELPDATA ),
  538. DPHELP_SHARED_NAME );
  539. }
  540. if( hsharedmem == NULL )
  541. {
  542. DPF( 1, "Could not create file mapping!" );
  543. return 0;
  544. }
  545. /*
  546. * create mutex for people who want to use the shared memory area
  547. */
  548. if (fUseGlobalNamespace)
  549. {
  550. hmutex = CreateMutex( DNGetNullDacl(), FALSE, "Global\\" DPHELP_MUTEX_NAME );
  551. }
  552. else
  553. {
  554. hmutex = CreateMutex( NULL, FALSE, DPHELP_MUTEX_NAME );
  555. }
  556. if( hmutex == NULL )
  557. {
  558. DPF( 1, "Could not create mutex " DPHELP_MUTEX_NAME );
  559. CloseHandle( hsharedmem );
  560. return 0;
  561. }
  562. /*
  563. * create events
  564. */
  565. if (fUseGlobalNamespace)
  566. {
  567. hstartevent = CreateEvent( DNGetNullDacl(), FALSE, FALSE, "Global\\" DPHELP_EVENT_NAME );
  568. }
  569. else
  570. {
  571. hstartevent = CreateEvent( NULL, FALSE, FALSE, DPHELP_EVENT_NAME );
  572. }
  573. if( hstartevent == NULL )
  574. {
  575. DPF( 1, "Could not create event " DPHELP_EVENT_NAME );
  576. CloseHandle( hmutex );
  577. CloseHandle( hsharedmem );
  578. return 0;
  579. }
  580. if (fUseGlobalNamespace)
  581. {
  582. hackevent = CreateEvent( DNGetNullDacl(), FALSE, FALSE, "Global\\" DPHELP_ACK_EVENT_NAME );
  583. }
  584. else
  585. {
  586. hackevent = CreateEvent( NULL, FALSE, FALSE, DPHELP_ACK_EVENT_NAME );
  587. }
  588. if( hackevent == NULL )
  589. {
  590. DPF( 1, "Could not create event " DPHELP_ACK_EVENT_NAME );
  591. CloseHandle( hmutex );
  592. CloseHandle( hsharedmem );
  593. CloseHandle( hstartevent );
  594. return 0;
  595. }
  596. /*
  597. * Create window so we can get messages
  598. */
  599. h = CreateThread(NULL,
  600. 0,
  601. (LPTHREAD_START_ROUTINE) WindowThreadProc,
  602. NULL,
  603. 0,
  604. (LPDWORD)&tid );
  605. if( h == NULL )
  606. {
  607. DPF( 1, "Create of WindowThreadProc FAILED!" );
  608. CloseHandle( hackevent );
  609. CloseHandle( hmutex );
  610. CloseHandle( hsharedmem );
  611. CloseHandle( hstartevent );
  612. return 0;
  613. }
  614. CloseHandle( h );
  615. /*
  616. * serialize access to us
  617. */
  618. INIT_DPLAYSVR_CSECT();
  619. if (!gbIPStarted)
  620. {
  621. rc = StartupIP();
  622. if (FAILED(rc))
  623. {
  624. DPF_ERR("dphelp : could not init wsock ! not adding server");
  625. return (rc);
  626. }
  627. }
  628. #if USE_RSIP
  629. bRsip=rsipInit();
  630. if(bRsip){
  631. rsipListenPort(FALSE, SERVER_DGRAM_PORT, NULL, NULL);
  632. }
  633. #endif
  634. #if USE_NATHELP
  635. natInit();
  636. if(g_pINatHelp){
  637. natRegisterUDPPort(SERVER_DGRAM_PORT);
  638. }
  639. #endif
  640. /*
  641. * let invoker and anyone else who comes along know we exist
  642. */
  643. SetEvent( hstartupevent );
  644. tLast=tNow=timeGetTime();
  645. /*
  646. * loop forever, processing requests
  647. */
  648. while( 1 )
  649. {
  650. wait:
  651. tWait=(tLast+RSIP_RENEW_TEST_INTERVAL)-tNow;
  652. if((int)tWait < 0){
  653. tWait=0;
  654. }
  655. ASSERT(!(tWait &0x80000000));
  656. /*
  657. * wait to be notified of a request
  658. */
  659. DPF( 1, "Waiting for next request" );
  660. rc = WaitForSingleObject( hstartevent, tWait );
  661. #if (USE_RSIP || USE_NATHELP)
  662. tNow=timeGetTime();
  663. if(rc==WAIT_TIMEOUT)
  664. {
  665. tLast=tNow;
  666. #if USE_RSIP
  667. if(bRsip) {rsipPortExtend(tNow);}
  668. #elif USE_NATHELP
  669. if(g_pINatHelp){natGetCapsUpdate();}
  670. #endif
  671. goto wait;
  672. }
  673. #endif
  674. if( rc == WAIT_FAILED )
  675. {
  676. DPF( 1, "Wait FAILED!!!" );
  677. continue;
  678. }
  679. ENTER_DPLAYSVR();
  680. phd = (LPDPHELPDATA) MapViewOfFile( hsharedmem, FILE_MAP_ALL_ACCESS, 0, 0, 0 );
  681. if( phd == NULL )
  682. {
  683. DPF( 1, "Could not create view of file!" );
  684. LEAVE_DPLAYSVR();
  685. continue;
  686. }
  687. /*
  688. * find out what we need to do
  689. */
  690. switch( phd->req )
  691. {
  692. case DPHELPREQ_SUICIDE:
  693. DPF( 1, "DPHELPREQ_SUICIDE" );
  694. #if USE_RSIP
  695. if(bRsip){
  696. rsipFini();
  697. }
  698. #endif
  699. #if USE_NATHELP
  700. if(g_pINatHelp){
  701. natFini();
  702. }
  703. #endif
  704. DPlayHelp_FreeServerList();
  705. SetEvent( hackevent );
  706. CloseHandle( hmutex );
  707. UnmapViewOfFile( phd );
  708. CloseHandle( hsharedmem );
  709. CloseHandle( hstartevent );
  710. if (gReceiveList.pConnection)
  711. {
  712. MemFree(gReceiveList.pConnection);
  713. }
  714. if (gReadfds.pfdbigset)
  715. {
  716. MemFree(gReadfds.pfdbigset);
  717. }
  718. FINI_DPLAYSVR_CSECT();
  719. // This should be done after functions that use a Dacl will no longer be
  720. // called (CreateMutex, CreateFile, etc).
  721. if (g_pEveryoneACL)
  722. {
  723. HeapFree(GetProcessHeap(), 0, g_pEveryoneACL);
  724. g_pEveryoneACL = NULL;
  725. g_psa = NULL;
  726. g_fDaclInited = FALSE;
  727. }
  728. #ifdef DEBUG
  729. MemState();
  730. #endif
  731. DPF( 3, "Good Night Gracie" );
  732. TerminateProcess( GetCurrentProcess(), 0 );
  733. break;
  734. case DPHELPREQ_RETURNHELPERPID:
  735. DPF( 2, "DDHELPREQ_RETURNHELPERPID" );
  736. phd->pid = GetCurrentProcessId();
  737. break;
  738. case DPHELPREQ_DPLAYADDSERVER:
  739. DPF( 2, "DPHELPREQ_DPLAYADDSERVER" );
  740. phd->hr = DPlayHelp_AddServer(phd);
  741. #if USE_RSIP
  742. if(!bRsip){
  743. bRsip=rsipInit();
  744. if(bRsip){
  745. rsipListenPort(FALSE, SERVER_DGRAM_PORT, NULL, NULL);
  746. }
  747. }
  748. #endif
  749. #if USE_NATHELP
  750. if(!g_pINatHelp){
  751. natInit();
  752. if(g_pINatHelp){
  753. natRegisterUDPPort(SERVER_DGRAM_PORT);
  754. }
  755. }
  756. #endif
  757. break;
  758. case DPHELPREQ_DPLAYDELETESERVER:
  759. DPF( 2, "DPHELPREQ_DPLAYDELETESERVER" );
  760. DPlayHelp_DeleteServer(phd,FALSE);
  761. break;
  762. default:
  763. DPF( 1, "helper - Unknown Request???" );
  764. break;
  765. }
  766. /*
  767. * let caller know we've got the news
  768. */
  769. UnmapViewOfFile( phd );
  770. SetEvent( hackevent );
  771. LEAVE_DPLAYSVR();
  772. }
  773. StopServiceProcess();
  774. } /* WinMain */