Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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