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.

1443 lines
43 KiB

  1. //---------------------------------------------------------------
  2. // Copyright (C)1998 Microsoft Corporation, All Rights Reserved.
  3. //
  4. // conn.cpp
  5. //
  6. // Connection mapping between sockets and CCONNECTION objects.
  7. //
  8. // Author:
  9. //
  10. // Edward Reus (edwardr) 02-26-98 Initial coding.
  11. //
  12. //---------------------------------------------------------------
  13. #include "precomp.h"
  14. #include <userenv.h>
  15. #include <time.h>
  16. #include <malloc.h>
  17. #ifdef DBG_MEM
  18. static LONG g_lCConnectionCount = 0;
  19. #endif
  20. //------------------------------------------------------------------------
  21. // CCONNECTION::CCONNECTION()
  22. //
  23. //------------------------------------------------------------------------
  24. CCONNECTION::CCONNECTION( IN DWORD dwKind,
  25. IN SOCKET Socket,
  26. IN HANDLE hIoCP,
  27. IN CSCEP_CONNECTION *pScepConnection,
  28. IN BOOL fSaveAsUPF )
  29. {
  30. this->SetKind(dwKind);
  31. m_pszServiceName = 0;
  32. m_hIoCompletionPort = hIoCP;
  33. m_ListenSocket = INVALID_SOCKET;
  34. m_Socket = Socket;
  35. m_hFile = INVALID_HANDLE_VALUE;
  36. m_pwszPathPlusFileName = 0;
  37. m_dwFileBytesWritten = 0;
  38. m_lPendingReads = 0;
  39. // m_lMaxPendingReads is set in SetKind().
  40. m_lPendingWrites = 0;
  41. // m_lMaxPendingWrites is set in SetKind().
  42. m_dwJpegOffset = 0;
  43. m_fSaveAsUPF = fSaveAsUPF;
  44. m_dwUpfBytes = 0;
  45. m_dwBytesWritten = 0;
  46. m_fReceiveComplete = FALSE;
  47. m_pScepConnection = pScepConnection;
  48. // If the new connection is to a camera, then tell the system that
  49. // we don't want it to hibrenate while the connection is active.
  50. if (m_dwKind != PACKET_KIND_LISTEN)
  51. {
  52. m_ExecutionState
  53. = SetThreadExecutionState( ES_SYSTEM_REQUIRED|ES_CONTINUOUS );
  54. }
  55. }
  56. //------------------------------------------------------------------------
  57. // CCONNECTION::~CCONNECTION()
  58. //
  59. //------------------------------------------------------------------------
  60. CCONNECTION::~CCONNECTION()
  61. {
  62. #if FALSE
  63. DbgPrint("CCONNECTION::~CCONNECTION(): Kind: %s Socket: %d\n",
  64. (m_dwKind == PACKET_KIND_LISTEN)?"Listen":"Read",
  65. (m_dwKind == PACKET_KIND_LISTEN)?m_ListenSocket:m_Socket);
  66. #endif
  67. if (m_pszServiceName)
  68. {
  69. FreeMemory(m_pszServiceName);
  70. }
  71. if ( (m_dwKind == PACKET_KIND_LISTEN)
  72. && (m_ListenSocket != INVALID_SOCKET))
  73. {
  74. closesocket(m_ListenSocket);
  75. }
  76. if (m_Socket != INVALID_SOCKET)
  77. {
  78. closesocket(m_Socket);
  79. }
  80. if (m_pScepConnection)
  81. {
  82. delete m_pScepConnection;
  83. }
  84. if (m_hFile != INVALID_HANDLE_VALUE)
  85. {
  86. CloseHandle(m_hFile);
  87. }
  88. if (m_pwszPathPlusFileName)
  89. {
  90. FreeMemory(m_pwszPathPlusFileName);
  91. }
  92. // Tell the system that it can go to sleep now if it wants
  93. // to...
  94. if (m_dwKind != PACKET_KIND_LISTEN)
  95. {
  96. SetThreadExecutionState( m_ExecutionState );
  97. }
  98. }
  99. //------------------------------------------------------------------------
  100. // CCONNECTION::operator new()
  101. //
  102. //------------------------------------------------------------------------
  103. void *CCONNECTION::operator new( IN size_t Size )
  104. {
  105. void *pObj = AllocateMemory(Size);
  106. #ifdef DBG_MEM
  107. if (pObj)
  108. {
  109. InterlockedIncrement(&g_lCConnectionCount);
  110. }
  111. DbgPrint("new CCONNECTION: Count: %d\n",g_lCConnectionCount);
  112. #endif
  113. return pObj;
  114. }
  115. //------------------------------------------------------------------------
  116. // CCONNECTION::operator delete()
  117. //
  118. //------------------------------------------------------------------------
  119. void CCONNECTION::operator delete( IN void *pObj,
  120. IN size_t Size )
  121. {
  122. if (pObj)
  123. {
  124. DWORD dwStatus = FreeMemory(pObj);
  125. #ifdef DBG_MEM
  126. if (dwStatus)
  127. {
  128. DbgPrint("IrXfer: IrTran-P: CCONNECTION::delete Failed: %d\n",
  129. dwStatus );
  130. }
  131. InterlockedDecrement(&g_lCConnectionCount);
  132. if (g_lCConnectionCount < 0)
  133. {
  134. DbgPrint("IrXfer: IrTran-P: CCONNECTION::delete: Count: %d\n",
  135. g_lCConnectionCount);
  136. }
  137. #endif
  138. }
  139. }
  140. //------------------------------------------------------------------------
  141. // CCONNECTION::InitializeForListen()
  142. //
  143. //------------------------------------------------------------------------
  144. DWORD CCONNECTION::InitializeForListen( IN char *pszServiceName,
  145. IN BOOL fIsIrCOMM,
  146. IN HANDLE hIoCP )
  147. {
  148. DWORD dwStatus = NO_ERROR;
  149. DWORD cb;
  150. SOCKADDR_IRDA AddrLocal;
  151. BYTE bIASSetBuffer[sizeof(IAS_SET) - 3 + IAS_SET_ATTRIB_MAX_LEN];
  152. int iIASSetSize = sizeof(bIASSetBuffer);
  153. IAS_SET *pIASSet = (IAS_SET*)bIASSetBuffer;
  154. int iEnable9WireMode = 1;
  155. // Connections are initialized in listen mode:
  156. SetKind(PACKET_KIND_LISTEN);
  157. // Save the service name for listen sockets:
  158. cb = 1+strlen(pszServiceName);
  159. m_pszServiceName = (char*)AllocateMemory(cb);
  160. if (m_pszServiceName)
  161. {
  162. StringCbCopyA(m_pszServiceName,cb,pszServiceName);
  163. }
  164. // Create a socket that we will listen on:
  165. m_ListenSocket = socket(AF_IRDA,SOCK_STREAM,IPPROTO_IP);
  166. if (m_ListenSocket == INVALID_SOCKET)
  167. {
  168. dwStatus = WSAGetLastError();
  169. return dwStatus;
  170. }
  171. // If this is IrCOMM, the we need to do a little extra work.
  172. if (fIsIrCOMM)
  173. {
  174. // Fill in the 9-wire attributes:
  175. memset(pIASSet,0,iIASSetSize);
  176. memcpy(pIASSet->irdaClassName,IRCOMM_9WIRE,sizeof(IRCOMM_9WIRE));
  177. memcpy(pIASSet->irdaAttribName,IRDA_PARAMETERS,sizeof(IRDA_PARAMETERS));
  178. pIASSet->irdaAttribType = IAS_ATTRIB_OCTETSEQ;
  179. pIASSet->irdaAttribute.irdaAttribOctetSeq.Len = OCTET_SEQ_SIZE;
  180. memcpy(pIASSet->irdaAttribute.irdaAttribOctetSeq.OctetSeq,OCTET_SEQ,OCTET_SEQ_SIZE);
  181. // Add IrCOMM IAS attributes for 3-wire cooked and 9-wire
  182. // raw modes (see the IrCOMM spec)...
  183. if (SOCKET_ERROR == setsockopt(m_ListenSocket,
  184. SOL_IRLMP,
  185. IRLMP_IAS_SET,
  186. (const char*)pIASSet,
  187. iIASSetSize))
  188. {
  189. dwStatus = WSAGetLastError();
  190. closesocket(m_ListenSocket);
  191. m_ListenSocket = INVALID_SOCKET;
  192. return dwStatus;
  193. }
  194. // Need to enable 9-wire mode before the bind():
  195. if (SOCKET_ERROR == setsockopt(m_ListenSocket,
  196. SOL_IRLMP,
  197. IRLMP_9WIRE_MODE,
  198. (const char*)&iEnable9WireMode,
  199. sizeof(iEnable9WireMode)))
  200. {
  201. dwStatus = WSAGetLastError();
  202. closesocket(m_ListenSocket);
  203. m_ListenSocket = INVALID_SOCKET;
  204. return dwStatus;
  205. }
  206. }
  207. // Setup the local address for the bind():
  208. memset(&AddrLocal,0,sizeof(AddrLocal));
  209. AddrLocal.irdaAddressFamily = AF_IRDA;
  210. StringCbCopyA(AddrLocal.irdaServiceName,sizeof(AddrLocal.irdaServiceName),pszServiceName);
  211. // Note: AddrLocal.irdaDeviceID ignored by server applications...
  212. if (SOCKET_ERROR == bind( m_ListenSocket,
  213. (struct sockaddr *)&AddrLocal,
  214. sizeof(AddrLocal)) )
  215. {
  216. dwStatus = WSAGetLastError();
  217. closesocket(m_ListenSocket);
  218. m_ListenSocket = INVALID_SOCKET;
  219. return dwStatus;
  220. }
  221. if (SOCKET_ERROR == listen(m_ListenSocket,2))
  222. {
  223. dwStatus = WSAGetLastError();
  224. closesocket(m_ListenSocket);
  225. m_ListenSocket = INVALID_SOCKET;
  226. return dwStatus;
  227. }
  228. hIoCP = CreateIoCompletionPort( (void*)m_ListenSocket,
  229. hIoCP,
  230. m_ListenSocket,
  231. 0 );
  232. m_hIoCompletionPort = hIoCP;
  233. return dwStatus;
  234. }
  235. //------------------------------------------------------------------------
  236. // CCONNECTION::PostMoreIos()
  237. //
  238. //------------------------------------------------------------------------
  239. DWORD CCONNECTION::PostMoreIos( CIOPACKET *pIoPacket )
  240. {
  241. DWORD dwStatus = 0;
  242. LONG lNumPendingReads;
  243. #ifdef DBG_IO
  244. if (m_dwKind == PACKET_KIND_LISTEN)
  245. {
  246. DbgPrint("CCONNECTION::PostMoreIos(): Listen: Socket: %d PendingReads: %d MaxPendingReads: %d\n",
  247. m_ListenSocket, m_lPendingReads, m_lMaxPendingReads );
  248. }
  249. else if (m_dwKind == PACKET_KIND_READ)
  250. {
  251. DbgPrint("CCONNECTION::PostMoreIos(): Read: Socket: %d PendingReads: %d MaxPendingReads: %d\n",
  252. m_Socket, m_lPendingReads, m_lMaxPendingReads );
  253. }
  254. #endif
  255. while (m_lPendingReads < m_lMaxPendingReads)
  256. {
  257. if (!pIoPacket)
  258. {
  259. pIoPacket = new CIOPACKET;
  260. if (!pIoPacket)
  261. {
  262. #ifdef DBG_ERROR
  263. DbgPrint("new CIOPACKET failed.\n");
  264. #endif
  265. dwStatus = ERROR_IRTRANP_OUT_OF_MEMORY;
  266. break;
  267. }
  268. dwStatus = pIoPacket->Initialize( GetKind(),
  269. GetListenSocket(),
  270. GetSocket(),
  271. GetIoCompletionPort() );
  272. }
  273. dwStatus = pIoPacket->PostIo();
  274. if (dwStatus != NO_ERROR)
  275. {
  276. #ifdef DBG_ERROR
  277. DbgPrint("pNewIoPacket->PostIo() failed: %d\n", dwStatus );
  278. #endif
  279. delete pIoPacket;
  280. break;
  281. }
  282. // Increment the count of the number of pending reads on
  283. // this connection:
  284. lNumPendingReads = IncrementPendingReads();
  285. ASSERT(lNumPendingReads > 0);
  286. pIoPacket = 0; // don't delete this line... this is a loop...
  287. }
  288. return dwStatus;
  289. }
  290. //------------------------------------------------------------------------
  291. // CCONNECTION::SendPdu()
  292. //
  293. //------------------------------------------------------------------------
  294. DWORD CCONNECTION::SendPdu( IN SCEP_HEADER *pPdu,
  295. IN DWORD dwPduSize,
  296. OUT CIOPACKET **ppIoPacket )
  297. {
  298. DWORD dwStatus = NO_ERROR;
  299. CIOPACKET *pIoPacket = new CIOPACKET;
  300. *ppIoPacket = 0;
  301. if (!pIoPacket)
  302. {
  303. return ERROR_IRTRANP_OUT_OF_MEMORY;
  304. }
  305. dwStatus = pIoPacket->Initialize( PACKET_KIND_WRITE_SOCKET,
  306. INVALID_SOCKET, // ListenSocket
  307. GetSocket(),
  308. GetIoCompletionPort() );
  309. if (dwStatus != NO_ERROR)
  310. {
  311. delete pIoPacket;
  312. return dwStatus;
  313. }
  314. dwStatus = pIoPacket->PostIoWrite(pPdu,dwPduSize,0);
  315. if (dwStatus != NO_ERROR)
  316. {
  317. delete pIoPacket;
  318. }
  319. else
  320. {
  321. *ppIoPacket = pIoPacket;
  322. }
  323. return dwStatus;
  324. }
  325. //------------------------------------------------------------------------
  326. // CCONNECTION::ShutdownSocket()
  327. //
  328. //------------------------------------------------------------------------
  329. DWORD CCONNECTION::ShutdownSocket()
  330. {
  331. DWORD dwStatus = NO_ERROR;
  332. WSAEVENT hEvent;
  333. if (m_Socket != INVALID_SOCKET)
  334. {
  335. if (SOCKET_ERROR == shutdown(m_Socket,SD_BOTH))
  336. {
  337. dwStatus = WSAGetLastError();
  338. return dwStatus;
  339. }
  340. }
  341. else if (m_ListenSocket != INVALID_SOCKET)
  342. {
  343. if (SOCKET_ERROR == shutdown(m_ListenSocket,SD_BOTH))
  344. {
  345. dwStatus = WSAGetLastError();
  346. return dwStatus;
  347. }
  348. }
  349. return dwStatus;
  350. }
  351. //------------------------------------------------------------------------
  352. // CCONNECTION::CloseSocket()
  353. //
  354. //------------------------------------------------------------------------
  355. void CCONNECTION::CloseSocket()
  356. {
  357. if (m_Socket != INVALID_SOCKET)
  358. {
  359. closesocket(m_Socket);
  360. m_Socket = INVALID_SOCKET;
  361. }
  362. }
  363. //------------------------------------------------------------------------
  364. // CCONNECTION::CloseListenSocket()
  365. //
  366. //------------------------------------------------------------------------
  367. void CCONNECTION::CloseListenSocket()
  368. {
  369. if (m_ListenSocket != INVALID_SOCKET)
  370. {
  371. closesocket(m_ListenSocket);
  372. m_ListenSocket = INVALID_SOCKET;
  373. }
  374. }
  375. //------------------------------------------------------------------------
  376. // CCONNECTION::CleanupDateString()
  377. //
  378. //------------------------------------------------------------------------
  379. void CCONNECTION::CleanupDateString( IN OUT WCHAR *pwszDateStr )
  380. {
  381. if (pwszDateStr)
  382. {
  383. while (*pwszDateStr)
  384. {
  385. if ((*pwszDateStr == L'/') || (*pwszDateStr == L'\\'))
  386. {
  387. *pwszDateStr = L'-';
  388. }
  389. else if (*pwszDateStr < 30)
  390. {
  391. *pwszDateStr = L'_';
  392. }
  393. pwszDateStr++;
  394. }
  395. }
  396. }
  397. //------------------------------------------------------------------------
  398. // CCONNECTION::ConstructPicturesSubDirectory()
  399. //
  400. // Generate the path for the directory where pictures will be stored
  401. // in.
  402. //
  403. // The return path string should be free'd using FreeMemory().
  404. //------------------------------------------------------------------------
  405. WCHAR *CCONNECTION::ConstructPicturesSubDirectory(
  406. IN DWORD dwExtraChars, OUT DWORD * pdwTotalChars )
  407. {
  408. # define MAX_DATE 64
  409. DWORD dwStatus = NO_ERROR;
  410. DWORD dwSize;
  411. DWORD dwLen = 0;
  412. DWORD dwUserDirectoryLen = 0;
  413. DWORD dwDateLen = 0;
  414. WCHAR *pwszDirectoryName = 0;
  415. WCHAR *pwszUserDirectory = 0;
  416. WCHAR wszDate[MAX_DATE];
  417. ASSERT (pdwTotalChars != NULL);
  418. *pdwTotalChars = 0;
  419. //
  420. // Get the target directory (~\My Documents\My Pictures):
  421. //
  422. pwszUserDirectory = GetUserDirectory();
  423. if (!pwszUserDirectory)
  424. {
  425. return 0;
  426. }
  427. dwUserDirectoryLen = wcslen(pwszUserDirectory);
  428. #ifdef DBG_IO
  429. DbgPrint("CCONNECTION::ConstructPicturesSubDirectory(): User Directory: %S\n",
  430. pwszUserDirectory);
  431. #endif
  432. //
  433. // Make sure the ~\My Pictures\ directory exists:
  434. //
  435. if (!CreateDirectory(pwszUserDirectory,0))
  436. {
  437. dwStatus = GetLastError();
  438. if ( (dwStatus == ERROR_ALREADY_EXISTS)
  439. || (dwStatus == ERROR_ACCESS_DENIED) )
  440. {
  441. dwStatus = NO_ERROR;
  442. }
  443. else if (dwStatus != NO_ERROR)
  444. {
  445. return 0;
  446. }
  447. }
  448. // Create a subdirectory under ~\My Pictures\ which is the current
  449. // date (i.e. MM-DD-YY), this is where the pictures will actually
  450. // be saved to:
  451. time_t now;
  452. struct tm *pTime;
  453. time(&now);
  454. pTime = localtime(&now);
  455. // NOTE: Use "%#x" for long date.
  456. if ( (pTime) && (wcsftime(wszDate,sizeof(wszDate)/sizeof(wszDate[0]),TEXT("%x"),pTime)) )
  457. {
  458. CleanupDateString(wszDate);
  459. #ifdef DBG_IO
  460. DbgPrint("CCONNECTION::ConstructPicturesSubDirectory(): Date: %S\n",
  461. wszDate );
  462. #endif
  463. dwDateLen = wcslen(wszDate);
  464. dwLen = sizeof(WCHAR)
  465. * (2
  466. +dwUserDirectoryLen
  467. +dwDateLen
  468. +dwExtraChars) ;
  469. pwszDirectoryName = (WCHAR*)AllocateMemory( dwLen );
  470. // NOTE: The extra 2 is for the '\' and a trailing zero.
  471. if (!pwszDirectoryName)
  472. {
  473. return 0;
  474. }
  475. StringCbCopyW(pwszDirectoryName,dwLen,pwszUserDirectory);
  476. if (pwszUserDirectory[dwUserDirectoryLen-1] != L'\\')
  477. {
  478. StringCbCatW(pwszDirectoryName,dwLen,TEXT("\\"));
  479. }
  480. StringCbCatW(pwszDirectoryName,dwLen,wszDate);
  481. dwStatus = NO_ERROR;
  482. if (!CreateDirectory(pwszDirectoryName,0))
  483. {
  484. dwStatus = GetLastError();
  485. if (dwStatus == ERROR_ALREADY_EXISTS)
  486. {
  487. dwStatus = NO_ERROR;
  488. }
  489. #ifdef DBG_ERROR
  490. else if (dwStatus != NO_ERROR)
  491. {
  492. DbgPrint("CCONNECTION::ConstructPicturesSubDirectory(): CreateDirectory(%S) failed: %d\n", pwszDirectoryName,dwStatus );
  493. FreeMemory(pwszDirectoryName);
  494. return 0;
  495. }
  496. #endif
  497. }
  498. if (dwStatus == NO_ERROR)
  499. {
  500. SetThumbnailView(pwszUserDirectory,pwszDirectoryName);
  501. }
  502. }
  503. #ifdef DBG_IO
  504. DbgPrint("CCONNECTION::ConstructPicturesSubDirectory(): Directory: %S\n",
  505. pwszDirectoryName);
  506. #endif
  507. *pdwTotalChars = dwLen / sizeof(WCHAR);
  508. return pwszDirectoryName;
  509. }
  510. //------------------------------------------------------------------------
  511. // CCONNECTION::SetThumbnailView()
  512. //
  513. // Default={5984FFE0-28D4-11CF-AE66-08002B2E1262}
  514. // {8BEBB290-52D0-11D0-B7F4-00C04FD706EC}={8BEBB290-52D0-11D0-B7F4-00C04FD706EC}
  515. // {5984FFE0-28D4-11CF-AE66-08002B2E1262}={5984FFE0-28D4-11CF-AE66-08002B2E1262}
  516. // [{5984FFE0-28D4-11CF-AE66-08002B2E1262}]
  517. // PersistMoniker=d:\winnt5\web\imgview.htt
  518. // PersistMonikerPreview=d:\winnt5\web\preview.bmp
  519. // [.ShellClassInfo]
  520. // ConfirmFileOp=0
  521. //
  522. //------------------------------------------------------------------------
  523. BOOL CCONNECTION::SetThumbnailView( IN WCHAR *pwszParentDirectoryName,
  524. IN WCHAR *pwszDirectoryName )
  525. {
  526. //
  527. // Configure the folder to have a "desktop.ini" file.
  528. //
  529. DWORD dwStatus = 0;
  530. DWORD cb;
  531. BOOL fStatus = PathMakeSystemFolderW(pwszDirectoryName);
  532. #ifdef DBG_ERROR
  533. if (!fStatus)
  534. {
  535. DbgPrint("CCONNECTION::SetThumbnailView(): PathMakeSystemFolderW() failed: %d\n",GetLastError());
  536. }
  537. #endif
  538. //
  539. // Create the "desktop.ini" file. First, try top copy it from the parent
  540. // directory (My Pictures). If that fails, then we will create it
  541. // ourselves (Picture Preview w/Thumbnail view on).
  542. //
  543. # define DESKTOP_INI TEXT("desktop.ini")
  544. HANDLE hFile;
  545. UINT uiSystemDirectorySize;
  546. WCHAR *pwszIniFile;
  547. WCHAR *pwszParentIniFile;
  548. BOOL fFailIfExists = TRUE;
  549. cb = sizeof(DESKTOP_INI)
  550. + sizeof(WCHAR) * (1 + wcslen(pwszDirectoryName));
  551. __try
  552. {
  553. pwszIniFile = (WCHAR*)_alloca( cb );
  554. }
  555. __except(EXCEPTION_EXECUTE_HANDLER)
  556. {
  557. return FALSE;
  558. }
  559. StringCbCopyW(pwszIniFile,cb,pwszDirectoryName);
  560. StringCbCatW(pwszIniFile,cb,TEXT("\\"));
  561. StringCbCatW(pwszIniFile,cb,DESKTOP_INI);
  562. cb = sizeof(DESKTOP_INI)
  563. + sizeof(WCHAR) * (1 + wcslen(pwszParentDirectoryName));
  564. __try
  565. {
  566. pwszParentIniFile = (WCHAR*)_alloca( cb );
  567. }
  568. __except(EXCEPTION_EXECUTE_HANDLER)
  569. {
  570. return FALSE;
  571. }
  572. StringCbCopyW(pwszParentIniFile,cb,pwszParentDirectoryName);
  573. StringCbCatW(pwszParentIniFile,cb,TEXT("\\"));
  574. StringCbCatW(pwszParentIniFile,cb,DESKTOP_INI);
  575. //
  576. // Try to get desktop.ini from the parent directory (My Pictures usually).
  577. //
  578. if (!CopyFileW(pwszParentIniFile,pwszIniFile,fFailIfExists))
  579. {
  580. dwStatus = GetLastError();
  581. #ifdef DBG_ERROR
  582. if (dwStatus != ERROR_FILE_EXISTS)
  583. {
  584. DbgPrint("CCONNECTION::SetThumbnailView(): copy %S to %S failed: dwStatus: %d\n", pwszParentIniFile, pwszIniFile, dwStatus );
  585. }
  586. #endif
  587. }
  588. if (dwStatus == ERROR_FILE_NOT_FOUND)
  589. {
  590. uiSystemDirectorySize = GetWindowsDirectoryA(NULL,0);
  591. ASSERT(uiSystemDirectorySize > 0);
  592. // Note: that in this case GetWindowsDirectoryA() is returning the
  593. // size, not the length...
  594. char *pszSystemDirectory;
  595. __try
  596. {
  597. pszSystemDirectory = (char*)_alloca(uiSystemDirectorySize);
  598. }
  599. __except(EXCEPTION_EXECUTE_HANDLER)
  600. {
  601. return FALSE;
  602. }
  603. UINT uiLen = GetWindowsDirectoryA(pszSystemDirectory,uiSystemDirectorySize);
  604. if (uiSystemDirectorySize != 1+uiLen)
  605. {
  606. #ifdef DBG_ERROR
  607. dwStatus = GetLastError();
  608. DbgPrint("CCONNECTION::ConstructPicturesSubDirectory(): GetWindowsDirectoryA() failed: %d\n",dwStatus);
  609. DbgPrint(" pszSystemDirectory: %s\n",pszSystemDirectory);
  610. DbgPrint(" uiSystemDirectorySize: %d\n",uiSystemDirectorySize);
  611. DbgPrint(" uiLen: %d\n",uiLen);
  612. #endif
  613. return TRUE;
  614. }
  615. # define FILE_CONTENTS_1 "[ExtShellFolderViews]\nDefault="\
  616. "{5984FFE0-28D4-11CF-AE66-08002B2E1262}\n"\
  617. "{8BEBB290-52D0-11D0-B7F4-00C04FD706EC}="\
  618. "{8BEBB290-52D0-11D0-B7F4-00C04FD706EC}\n"\
  619. "{5984FFE0-28D4-11CF-AE66-08002B2E1262}="\
  620. "{5984FFE0-28D4-11CF-AE66-08002B2E1262}\n"\
  621. "[{5984FFE0-28D4-11CF-AE66-08002B2E1262}]\n"\
  622. "PersistMoniker="
  623. # define FILE_CONTENTS_2 "\\web\\imgview.htt\nPersistMonikerPreview="
  624. # define FILE_CONTENTS_3 "\\web\\preview.bmp\n[.ShellClassInfo]\nConfirmFileOp=0\n"
  625. hFile = CreateFileW( pwszIniFile,
  626. GENERIC_WRITE, // dwAccess
  627. 0, // dwShareMode (no sharing).
  628. NULL, // pSecurityAttributes
  629. CREATE_NEW, // dwDisposition
  630. FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
  631. NULL ); // hTemplate
  632. if (hFile != INVALID_HANDLE_VALUE)
  633. {
  634. cb = sizeof(FILE_CONTENTS_1)
  635. + sizeof(FILE_CONTENTS_2)
  636. + sizeof(FILE_CONTENTS_3)
  637. + 2*uiSystemDirectorySize;
  638. char *pszFileContents;
  639. __try
  640. {
  641. pszFileContents = (char*)_alloca( cb );
  642. }
  643. __except(EXCEPTION_EXECUTE_HANDLER)
  644. {
  645. return FALSE;
  646. }
  647. StringCbCopyA(pszFileContents,cb,FILE_CONTENTS_1);
  648. StringCbCatA(pszFileContents,cb,pszSystemDirectory);
  649. StringCbCatA(pszFileContents,cb,FILE_CONTENTS_2);
  650. StringCbCatA(pszFileContents,cb,pszSystemDirectory);
  651. StringCbCatA(pszFileContents,cb,FILE_CONTENTS_3);
  652. DWORD dwBytes = strlen(pszFileContents);
  653. DWORD dwBytesWritten = 0;
  654. WriteFile(hFile,pszFileContents,dwBytes,&dwBytesWritten,NULL);
  655. CloseHandle(hFile);
  656. }
  657. }
  658. return TRUE;
  659. }
  660. //------------------------------------------------------------------------
  661. // CCONNECTION::ConstructFullFileName()
  662. //
  663. // Generate the path + file name that the picture will be stored
  664. // in. If dwCopyCount is zero, then its just a straight file name.
  665. // If dwCopyCount is N, then "N_" is prefixed to the file name.
  666. //------------------------------------------------------------------------
  667. WCHAR *CCONNECTION::ConstructFullFileName( IN DWORD dwCopyCount )
  668. {
  669. # define MAX_DATE 64
  670. # define MAX_PREFIX 64
  671. DWORD dwLen;
  672. DWORD dwFileNameLen;
  673. DWORD dwPrefixStrLen;
  674. DWORD dwExtraChars;
  675. WCHAR *pwszFullFileName = 0; // Path + file name.
  676. WCHAR *pwszFileName = 0; // File name only.
  677. WCHAR wszPrefixStr[MAX_PREFIX];
  678. if (!m_pScepConnection)
  679. {
  680. return 0;
  681. }
  682. pwszFileName = m_pScepConnection->GetFileName();
  683. if (!pwszFileName)
  684. {
  685. return 0;
  686. }
  687. dwFileNameLen = wcslen(pwszFileName);
  688. if (dwCopyCount == 0)
  689. {
  690. dwExtraChars = 1 + dwFileNameLen; // Extra 1 for the "\".
  691. }
  692. else
  693. {
  694. _itow(dwCopyCount,wszPrefixStr,10);
  695. StringCchCat(wszPrefixStr,sizeof(wszPrefixStr)/sizeof(wszPrefixStr[0]),TEXT("_"));
  696. dwPrefixStrLen = wcslen(wszPrefixStr);
  697. dwExtraChars = 1 + dwFileNameLen + dwPrefixStrLen;
  698. }
  699. pwszFullFileName = CCONNECTION::ConstructPicturesSubDirectory(dwExtraChars, &dwLen);
  700. if (!pwszFullFileName)
  701. {
  702. return 0;
  703. }
  704. if (dwCopyCount == 0)
  705. {
  706. StringCchCat(pwszFullFileName,dwLen,TEXT("\\"));
  707. StringCchCat(pwszFullFileName,dwLen,pwszFileName);
  708. }
  709. else
  710. {
  711. StringCchCat(pwszFullFileName,dwLen,TEXT("\\"));
  712. StringCchCat(pwszFullFileName,dwLen,wszPrefixStr);
  713. StringCchCat(pwszFullFileName,dwLen,pwszFileName);
  714. }
  715. #ifdef DBG_IO
  716. DbgPrint("CCONNECTION::ConstructFullFileName(): return: %S\n",
  717. pwszFullFileName);
  718. #endif
  719. return pwszFullFileName;
  720. }
  721. //------------------------------------------------------------------------
  722. // CCONNECTION::CreatePictureFile()
  723. //
  724. //------------------------------------------------------------------------
  725. DWORD CCONNECTION::CreatePictureFile()
  726. {
  727. DWORD dwStatus = NO_ERROR;
  728. DWORD dwFlags = FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED;
  729. WCHAR *pwszFile;
  730. WCHAR *pwszPathPlusFileName = 0;
  731. HANDLE hIoCP;
  732. // Make sure that the counters start at zero:
  733. m_dwUpfBytes = 0;
  734. m_dwBytesWritten = 0;
  735. // See if we already have an image file open, if yes then
  736. // close it.
  737. if (m_hFile != INVALID_HANDLE_VALUE)
  738. {
  739. CloseHandle(m_hFile);
  740. }
  741. // Get the full path + name for the file we will create.
  742. // Note, that ConstructFullFileName() may create a subdirectory,
  743. // so it needs to be done after the impersonation...
  744. // This is important if we have a remoted \My Documents\
  745. // directory.
  746. DWORD dwCopyCount;
  747. for (dwCopyCount=0; dwCopyCount<=MAX_COPYOF_TRIES; dwCopyCount++)
  748. {
  749. pwszPathPlusFileName = ConstructFullFileName(dwCopyCount);
  750. if (!pwszPathPlusFileName)
  751. {
  752. return ERROR_SCEP_CANT_CREATE_FILE;
  753. }
  754. // Try to create new image (JPEG) file:
  755. m_hFile = CreateFile( pwszPathPlusFileName,
  756. GENERIC_WRITE,
  757. 0, // Share mode (none).
  758. 0, // Security attribute.
  759. CREATE_NEW, // Open mode.
  760. dwFlags, // Attributes.
  761. 0 ); // Template file (none).
  762. if (m_hFile != INVALID_HANDLE_VALUE)
  763. {
  764. // Successfully created the file, now associate it with
  765. // our IO completion port:
  766. hIoCP = CreateIoCompletionPort( m_hFile,
  767. m_hIoCompletionPort,
  768. (DWORD)m_Socket,
  769. 0 );
  770. if (!hIoCP)
  771. {
  772. dwStatus = GetLastError();
  773. #ifdef DBG_ERROR
  774. DbgPrint("CCONNECTION::CreatePictureFile(): CreateIoCompletionPort() failed: %d\n",dwStatus);
  775. #endif
  776. CloseHandle(m_hFile);
  777. m_hFile = INVALID_HANDLE_VALUE;
  778. FreeMemory(pwszPathPlusFileName);
  779. break;
  780. }
  781. // This is the success exit point.
  782. m_pwszPathPlusFileName = pwszPathPlusFileName;
  783. break;
  784. }
  785. else
  786. {
  787. dwStatus = GetLastError();
  788. if (dwStatus != ERROR_FILE_EXISTS)
  789. {
  790. #ifdef DBG_TARGET_DIR
  791. DbgPrint("CCONNECTION::CreatePictureFile(): CreateFile(): %S Failed: %d\n",pwszPathPlusFileName,dwStatus);
  792. #endif
  793. FreeMemory(pwszPathPlusFileName);
  794. break;
  795. }
  796. // If we get here, then then a picture file by that name
  797. // alreay exists, so try again...
  798. FreeMemory(pwszPathPlusFileName);
  799. }
  800. }
  801. return dwStatus;
  802. }
  803. //------------------------------------------------------------------------
  804. // CCONNECTION::SetPictureFileTime()
  805. //
  806. //------------------------------------------------------------------------
  807. DWORD CCONNECTION::SetPictureFileTime( IN FILETIME *pFileTime )
  808. {
  809. DWORD dwStatus = NO_ERROR;
  810. if (!pFileTime)
  811. {
  812. #ifdef DBG_DATE
  813. DbgPrint("IrTranP: SetFileTime(): no time to set\n");
  814. #endif
  815. return dwStatus; // Empty case, no time to set.
  816. }
  817. if (!SetFileTime(m_hFile,pFileTime,pFileTime,pFileTime))
  818. {
  819. dwStatus = GetLastError();
  820. #ifdef DBG_DATE
  821. DbgPrint("IrTranP: SetFileTime() Failed: %d\n",dwStatus);
  822. #endif
  823. }
  824. return dwStatus;
  825. }
  826. //------------------------------------------------------------------------
  827. // CCONNECTION::WritePictureFile()
  828. //
  829. //------------------------------------------------------------------------
  830. DWORD CCONNECTION::WritePictureFile( IN UCHAR *pBuffer,
  831. IN DWORD dwBufferSize,
  832. OUT CIOPACKET **ppIoPacket )
  833. {
  834. DWORD dwStatus = NO_ERROR;
  835. DWORD dwOffset = m_dwBytesWritten;
  836. DWORD dwBytesToWrite;
  837. LONG lPendingWrites;
  838. *ppIoPacket = 0;
  839. CIOPACKET *pIoPacket = new CIOPACKET;
  840. if (!pIoPacket)
  841. {
  842. return ERROR_IRTRANP_OUT_OF_MEMORY;
  843. }
  844. dwStatus = pIoPacket->Initialize( PACKET_KIND_WRITE_FILE,
  845. INVALID_SOCKET, // ListenSocket
  846. INVALID_SOCKET, // Camera...
  847. GetIoCompletionPort() );
  848. if (dwStatus != NO_ERROR)
  849. {
  850. delete pIoPacket;
  851. return dwStatus;
  852. }
  853. pIoPacket->SetFileHandle(m_hFile);
  854. //
  855. // If we are writing just the JPEG image out of the UPF file,
  856. // then we don't want to write the first m_dwJpegOffset bytes
  857. // of the UPF file.
  858. //
  859. if ((m_dwUpfBytes >= m_dwJpegOffset) || (m_fSaveAsUPF))
  860. {
  861. dwBytesToWrite = dwBufferSize;
  862. }
  863. else if ((m_dwUpfBytes + dwBufferSize) > m_dwJpegOffset)
  864. {
  865. dwBytesToWrite = (m_dwUpfBytes + dwBufferSize) - m_dwJpegOffset;
  866. for (DWORD i=0; i<dwBytesToWrite; i++)
  867. {
  868. pBuffer[i] = pBuffer[i+m_dwJpegOffset-m_dwUpfBytes];
  869. }
  870. }
  871. else
  872. {
  873. dwBytesToWrite = 0;
  874. }
  875. //
  876. // When we start writing the JPEG file we want to cut off the
  877. // file save writes once we've written out the m_dwJpegSize
  878. // bytes that are the JPEG image inside of the UPF file.
  879. //
  880. if (!m_fSaveAsUPF)
  881. {
  882. if (m_dwBytesWritten < m_dwJpegSize)
  883. {
  884. if ((m_dwBytesWritten+dwBytesToWrite) > m_dwJpegSize)
  885. {
  886. dwBytesToWrite = m_dwJpegSize - m_dwBytesWritten;
  887. }
  888. }
  889. else
  890. {
  891. dwBytesToWrite = 0;
  892. }
  893. }
  894. //
  895. // If there are bytes to actually write, then let's do it.
  896. //
  897. if (dwBytesToWrite > 0)
  898. {
  899. dwStatus = pIoPacket->PostIoWrite(pBuffer,dwBytesToWrite,dwOffset);
  900. if (dwStatus == NO_ERROR)
  901. {
  902. lPendingWrites = IncrementPendingWrites();
  903. ASSERT( lPendingWrites > 0 );
  904. m_dwBytesWritten += dwBytesToWrite;
  905. *ppIoPacket = pIoPacket;
  906. }
  907. }
  908. else
  909. {
  910. delete pIoPacket;
  911. }
  912. m_dwUpfBytes += dwBufferSize;
  913. return dwStatus;
  914. }
  915. //------------------------------------------------------------------------
  916. // CCONNECTION::DeletePictureFile()
  917. //
  918. //------------------------------------------------------------------------
  919. DWORD CCONNECTION::DeletePictureFile()
  920. {
  921. DWORD dwStatus = NO_ERROR;
  922. if (m_hFile == INVALID_HANDLE_VALUE)
  923. {
  924. return NO_ERROR;
  925. }
  926. CloseHandle(m_hFile);
  927. m_hFile = INVALID_HANDLE_VALUE;
  928. if (m_pwszPathPlusFileName)
  929. {
  930. #ifdef DBG_IO
  931. DbgPrint("CCONNECTION::DeletePictureFile(): Delete: %S\n",
  932. m_pwszPathPlusFileName );
  933. #endif
  934. DeleteFile(m_pwszPathPlusFileName);
  935. }
  936. return dwStatus;
  937. }
  938. //------------------------------------------------------------------------
  939. // CCONNECTION::ClosePictureFile()
  940. //
  941. //------------------------------------------------------------------------
  942. DWORD CCONNECTION::ClosePictureFile()
  943. {
  944. DWORD dwStatus = NO_ERROR;
  945. if (m_pwszPathPlusFileName)
  946. {
  947. FreeMemory(m_pwszPathPlusFileName);
  948. m_pwszPathPlusFileName = 0;
  949. }
  950. if (m_hFile != INVALID_HANDLE_VALUE)
  951. {
  952. if (!CloseHandle(m_hFile))
  953. {
  954. dwStatus = GetLastError();
  955. }
  956. m_hFile = INVALID_HANDLE_VALUE;
  957. }
  958. return dwStatus;
  959. }
  960. //------------------------------------------------------------------------
  961. // CCONNECTION::IncompleteFile()
  962. //
  963. // Check to see if we have a complete picture file, if yes, then return
  964. // FALSE, else return TRUE.
  965. //------------------------------------------------------------------------
  966. BOOL CCONNECTION::IncompleteFile()
  967. {
  968. BOOL fIncomplete = FALSE;
  969. if (m_fSaveAsUPF)
  970. {
  971. // Note: currently save the .UPF file, even if its incomplete.
  972. // This file mode is set in the registry and is for testing
  973. // only...
  974. fIncomplete = FALSE;
  975. }
  976. else if (!m_fReceiveComplete)
  977. {
  978. fIncomplete = (m_dwBytesWritten < m_dwJpegSize);
  979. #ifdef DBG_IO
  980. DbgPrint("CCONNECTION::IncompleteFile(): Written: %d JPEG Size: %d\n",
  981. m_dwBytesWritten, m_dwJpegSize );
  982. #endif
  983. }
  984. return fIncomplete;
  985. }
  986. //************************************************************************
  987. //------------------------------------------------------------------------
  988. // CCONNECTION_MAP::CCONNECTION_MAP()
  989. //
  990. //------------------------------------------------------------------------
  991. CCONNECTION_MAP::CCONNECTION_MAP()
  992. {
  993. m_dwMapSize = 0;
  994. m_pMap = 0;
  995. }
  996. //------------------------------------------------------------------------
  997. // CCONNECTION_MAP::~CCONNECTION_MAP()
  998. //
  999. //------------------------------------------------------------------------
  1000. CCONNECTION_MAP::~CCONNECTION_MAP()
  1001. {
  1002. if (m_pMap)
  1003. {
  1004. DeleteCriticalSection(&m_cs);
  1005. FreeMemory(m_pMap);
  1006. }
  1007. }
  1008. //------------------------------------------------------------------------
  1009. // CCONNECTION_MAP::operator new()
  1010. //
  1011. //------------------------------------------------------------------------
  1012. void *CCONNECTION_MAP::operator new( IN size_t Size )
  1013. {
  1014. void *pObj = AllocateMemory(Size);
  1015. return pObj;
  1016. }
  1017. //------------------------------------------------------------------------
  1018. // CCONNECTION_MAP::operator delete()
  1019. //
  1020. //------------------------------------------------------------------------
  1021. void CCONNECTION_MAP::operator delete( IN void *pObj,
  1022. IN size_t Size )
  1023. {
  1024. if (pObj)
  1025. {
  1026. DWORD dwStatus = FreeMemory(pObj);
  1027. #ifdef DBG_MEM
  1028. if (dwStatus)
  1029. {
  1030. DbgPrint("IrXfer: IrTran-P: CCONNECTION_MAP::delete Failed: %d\n",
  1031. dwStatus );
  1032. }
  1033. #endif
  1034. }
  1035. }
  1036. //------------------------------------------------------------------------
  1037. // CCONNECTION_MAP::Initialize()
  1038. //
  1039. //------------------------------------------------------------------------
  1040. BOOL CCONNECTION_MAP::Initialize( IN DWORD dwNewMapSize )
  1041. {
  1042. BOOL bResult;
  1043. if (!dwNewMapSize)
  1044. {
  1045. return FALSE;
  1046. }
  1047. if (!m_dwMapSize)
  1048. {
  1049. m_pMap = (CONNECTION_MAP_ENTRY*)AllocateMemory( dwNewMapSize*sizeof(CONNECTION_MAP_ENTRY) );
  1050. if (!m_pMap)
  1051. {
  1052. return FALSE;
  1053. }
  1054. bResult=InitializeCriticalSectionAndSpinCount(&m_cs,0);
  1055. if (!bResult)
  1056. {
  1057. FreeMemory(m_pMap);
  1058. m_pMap = 0;
  1059. return FALSE;
  1060. }
  1061. m_dwMapSize = dwNewMapSize;
  1062. memset(m_pMap,0,m_dwMapSize*sizeof(CONNECTION_MAP_ENTRY));
  1063. }
  1064. return TRUE;
  1065. }
  1066. //------------------------------------------------------------------------
  1067. // CCONNECTION_MAP::Lookup()
  1068. //
  1069. //------------------------------------------------------------------------
  1070. CCONNECTION *CCONNECTION_MAP::Lookup( IN SOCKET Socket )
  1071. {
  1072. DWORD i;
  1073. NTSTATUS Status;
  1074. CCONNECTION *pConnection=NULL;
  1075. if (m_dwMapSize == 0)
  1076. {
  1077. return 0;
  1078. }
  1079. EnterCriticalSection(&m_cs);
  1080. for (i=0; i<m_dwMapSize; i++)
  1081. {
  1082. if (m_pMap[i].Socket == Socket)
  1083. {
  1084. pConnection=m_pMap[i].pConnection;
  1085. break;
  1086. }
  1087. }
  1088. LeaveCriticalSection(&m_cs);
  1089. return pConnection;
  1090. }
  1091. //------------------------------------------------------------------------
  1092. // CCONNECTION_MAP::LookupByServiceName()
  1093. //
  1094. //------------------------------------------------------------------------
  1095. CCONNECTION *CCONNECTION_MAP::LookupByServiceName( IN char *pszServiceName )
  1096. {
  1097. DWORD i;
  1098. NTSTATUS Status;
  1099. CCONNECTION *pConnection;
  1100. if (m_dwMapSize == 0)
  1101. {
  1102. return 0;
  1103. }
  1104. EnterCriticalSection(&m_cs);
  1105. for (i=0; i<m_dwMapSize; i++)
  1106. {
  1107. pConnection = m_pMap[i].pConnection;
  1108. if ( (pConnection)
  1109. && (pConnection->GetServiceName())
  1110. && (!strcmp(pConnection->GetServiceName(),pszServiceName)))
  1111. {
  1112. LeaveCriticalSection(&m_cs);
  1113. return pConnection;
  1114. }
  1115. }
  1116. LeaveCriticalSection(&m_cs);
  1117. return 0;
  1118. }
  1119. //------------------------------------------------------------------------
  1120. // CCONNECTION_MAP::Add()
  1121. //
  1122. //------------------------------------------------------------------------
  1123. BOOL CCONNECTION_MAP::Add( IN CCONNECTION *pConnection,
  1124. IN SOCKET Socket )
  1125. {
  1126. DWORD i;
  1127. // Only add entries that look valid...
  1128. if ((Socket == 0)||(Socket==INVALID_SOCKET)||(pConnection == 0))
  1129. {
  1130. return FALSE;
  1131. }
  1132. EnterCriticalSection(&m_cs);
  1133. // Look for an empty place in the table:
  1134. for (i=0; i<m_dwMapSize; i++)
  1135. {
  1136. if (m_pMap[i].Socket == 0)
  1137. {
  1138. m_pMap[i].Socket = Socket;
  1139. m_pMap[i].pConnection = pConnection;
  1140. LeaveCriticalSection(&m_cs);
  1141. return TRUE;
  1142. }
  1143. }
  1144. // The table is full, expand it...
  1145. DWORD dwNewMapSize = 3*m_dwMapSize/2; // 50% bigger.
  1146. CONNECTION_MAP_ENTRY *pMap = (CONNECTION_MAP_ENTRY*)AllocateMemory( dwNewMapSize*sizeof(CONNECTION_MAP_ENTRY) );
  1147. if (!pMap)
  1148. {
  1149. LeaveCriticalSection(&m_cs);
  1150. return FALSE; // Out of memory...
  1151. }
  1152. memset(pMap,0,dwNewMapSize*sizeof(CONNECTION_MAP_ENTRY));
  1153. for (i=0; i<m_dwMapSize; i++)
  1154. {
  1155. pMap[i].Socket = m_pMap[i].Socket;
  1156. pMap[i].pConnection = m_pMap[i].pConnection;
  1157. }
  1158. pMap[i].Socket = Socket;
  1159. pMap[i].pConnection = pConnection;
  1160. FreeMemory(m_pMap);
  1161. m_pMap = pMap;
  1162. m_dwMapSize = dwNewMapSize;
  1163. LeaveCriticalSection(&m_cs);
  1164. return TRUE;
  1165. }
  1166. //------------------------------------------------------------------------
  1167. // CCONNECTION_MAP::Remove()
  1168. //
  1169. //------------------------------------------------------------------------
  1170. CCONNECTION *CCONNECTION_MAP::Remove( IN SOCKET Socket )
  1171. {
  1172. DWORD i;
  1173. CCONNECTION *pConnection;
  1174. EnterCriticalSection(&m_cs);
  1175. for (i=0; i<m_dwMapSize; i++)
  1176. {
  1177. if (m_pMap[i].Socket == Socket)
  1178. {
  1179. pConnection = m_pMap[i].pConnection;
  1180. m_pMap[i].Socket = 0;
  1181. m_pMap[i].pConnection = 0;
  1182. LeaveCriticalSection(&m_cs);
  1183. return pConnection;
  1184. }
  1185. }
  1186. LeaveCriticalSection(&m_cs);
  1187. return 0;
  1188. }
  1189. //------------------------------------------------------------------------
  1190. // CCONNECTION_MAP::RemoveConnection()
  1191. //
  1192. //------------------------------------------------------------------------
  1193. CCONNECTION *CCONNECTION_MAP::RemoveConnection( IN CCONNECTION *pConnection )
  1194. {
  1195. DWORD i;
  1196. EnterCriticalSection(&m_cs);
  1197. for (i=0; i<m_dwMapSize; i++)
  1198. {
  1199. if (m_pMap[i].pConnection == pConnection)
  1200. {
  1201. m_pMap[i].Socket = 0;
  1202. m_pMap[i].pConnection = 0;
  1203. LeaveCriticalSection(&m_cs);
  1204. return pConnection;
  1205. }
  1206. }
  1207. LeaveCriticalSection(&m_cs);
  1208. return 0;
  1209. }
  1210. //------------------------------------------------------------------------
  1211. // CCONNECTION_MAP::RemoveNext()
  1212. //
  1213. // Walk through the connection map and get the next entry, remove the
  1214. // entry from the map as well.
  1215. //------------------------------------------------------------------------
  1216. CCONNECTION *CCONNECTION_MAP::RemoveNext()
  1217. {
  1218. DWORD i;
  1219. CCONNECTION *pConnection;
  1220. EnterCriticalSection(&m_cs);
  1221. for (i=0; i<m_dwMapSize; i++)
  1222. {
  1223. if (m_pMap[i].Socket)
  1224. {
  1225. pConnection = m_pMap[i].pConnection;
  1226. m_pMap[i].Socket = 0;
  1227. m_pMap[i].pConnection = 0;
  1228. LeaveCriticalSection(&m_cs);
  1229. return pConnection;
  1230. }
  1231. }
  1232. LeaveCriticalSection(&m_cs);
  1233. return 0;
  1234. }