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.

1268 lines
36 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. extern HINSTANCE g_hInst; // Instance of ircamera.dll
  22. //------------------------------------------------------------------------
  23. // CCONNECTION::CCONNECTION()
  24. //
  25. //------------------------------------------------------------------------
  26. CCONNECTION::CCONNECTION( IN DWORD dwKind,
  27. IN SOCKET Socket,
  28. IN HANDLE hIoCP,
  29. IN CSCEP_CONNECTION *pScepConnection,
  30. IN BOOL fSaveAsUPF )
  31. {
  32. this->SetKind(dwKind);
  33. m_pszServiceName = 0;
  34. m_ListenSocket = INVALID_SOCKET;
  35. m_Socket = Socket;
  36. m_hFile = INVALID_HANDLE_VALUE;
  37. m_pszPathPlusFileName = 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. #ifdef USE_WINNT_CALLS
  55. m_ExecutionState
  56. = SetThreadExecutionState( ES_SYSTEM_REQUIRED|ES_CONTINUOUS );
  57. #else
  58. #pragma message("Missing important call: SetThreadExecutionState on Windows9x ")
  59. #endif
  60. }
  61. }
  62. //------------------------------------------------------------------------
  63. // CCONNECTION::~CCONNECTION()
  64. //
  65. //------------------------------------------------------------------------
  66. CCONNECTION::~CCONNECTION()
  67. {
  68. if (m_pszServiceName)
  69. {
  70. FreeMemory(m_pszServiceName);
  71. }
  72. if ( (m_dwKind == PACKET_KIND_LISTEN)
  73. && (m_ListenSocket != INVALID_SOCKET))
  74. {
  75. closesocket(m_ListenSocket);
  76. }
  77. if (m_Socket != INVALID_SOCKET)
  78. {
  79. closesocket(m_Socket);
  80. }
  81. if (m_pScepConnection)
  82. {
  83. delete m_pScepConnection;
  84. }
  85. if (m_hFile != INVALID_HANDLE_VALUE)
  86. {
  87. CloseHandle(m_hFile);
  88. }
  89. if (m_pszPathPlusFileName)
  90. {
  91. FreeMemory(m_pszPathPlusFileName);
  92. }
  93. // Tell the system that it can go to sleep now if it wants
  94. // to...
  95. if (m_dwKind != PACKET_KIND_LISTEN)
  96. {
  97. #ifdef USE_WINNT_CALLS
  98. SetThreadExecutionState( m_ExecutionState );
  99. #else
  100. #pragma message("Missing important call SetThreadExecutionState on Windows9x ")
  101. #endif
  102. }
  103. }
  104. //------------------------------------------------------------------------
  105. // CCONNECTION::operator new()
  106. //
  107. //------------------------------------------------------------------------
  108. void *CCONNECTION::operator new( IN size_t Size )
  109. {
  110. void *pObj = AllocateMemory(Size);
  111. return pObj;
  112. }
  113. //------------------------------------------------------------------------
  114. // CCONNECTION::operator delete()
  115. //
  116. //------------------------------------------------------------------------
  117. void CCONNECTION::operator delete( IN void *pObj,
  118. IN size_t Size )
  119. {
  120. if (pObj)
  121. {
  122. DWORD dwStatus = FreeMemory(pObj);
  123. }
  124. }
  125. //------------------------------------------------------------------------
  126. // CCONNECTION::InitializeForListen()
  127. //
  128. //------------------------------------------------------------------------
  129. DWORD CCONNECTION::InitializeForListen( IN char *pszServiceName,
  130. IN BOOL fIsIrCOMM,
  131. IN HANDLE hIoCP )
  132. {
  133. DWORD dwStatus = NO_ERROR;
  134. SOCKADDR_IRDA AddrLocal;
  135. BYTE bIASSetBuffer[sizeof(IAS_SET) - 3 + IAS_SET_ATTRIB_MAX_LEN];
  136. int iIASSetSize = sizeof(bIASSetBuffer);
  137. IAS_SET *pIASSet = (IAS_SET*)bIASSetBuffer;
  138. int iEnable9WireMode = 1;
  139. // Connections are initialized in listen mode:
  140. SetKind(PACKET_KIND_LISTEN);
  141. // Save the service name for listen sockets:
  142. m_pszServiceName = (char*)AllocateMemory(1+strlen(pszServiceName));
  143. if (m_pszServiceName)
  144. {
  145. strcpy(m_pszServiceName,pszServiceName);
  146. }
  147. // Create a socket that we will listen on:
  148. m_ListenSocket = socket(AF_IRDA,SOCK_STREAM,IPPROTO_IP);
  149. if (m_ListenSocket == INVALID_SOCKET)
  150. {
  151. dwStatus = WSAGetLastError();
  152. #ifdef DBG_ERROR
  153. WIAS_ERROR((g_hInst,"InitializeForListen(%s): socket() Failed: %d\n",pszServiceName,dwStatus));
  154. #endif
  155. return dwStatus;
  156. }
  157. // If this is IrCOMM, the we need to do a little extra work.
  158. if (fIsIrCOMM)
  159. {
  160. // Fill in the 9-wire attributes:
  161. memset(pIASSet,0,iIASSetSize);
  162. memcpy(pIASSet->irdaClassName,IRCOMM_9WIRE,sizeof(IRCOMM_9WIRE));
  163. memcpy(pIASSet->irdaAttribName,IRDA_PARAMETERS,sizeof(IRDA_PARAMETERS));
  164. pIASSet->irdaAttribType = IAS_ATTRIB_OCTETSEQ;
  165. pIASSet->irdaAttribute.irdaAttribOctetSeq.Len = OCTET_SEQ_SIZE;
  166. memcpy(pIASSet->irdaAttribute.irdaAttribOctetSeq.OctetSeq,OCTET_SEQ,OCTET_SEQ_SIZE);
  167. // Add IrCOMM IAS attributes for 3-wire cooked and 9-wire
  168. // raw modes (see the IrCOMM spec)...
  169. if (SOCKET_ERROR == setsockopt(m_ListenSocket,
  170. SOL_IRLMP,
  171. IRLMP_IAS_SET,
  172. (const char*)pIASSet,
  173. iIASSetSize))
  174. {
  175. dwStatus = WSAGetLastError();
  176. #ifdef DBG_ERROR
  177. WIAS_TRACE((g_hInst,"InitializeForListen(%s): setsockopt(IRLMP_IAS_SET) Failed: %d",pszServiceName,dwStatus));
  178. #endif
  179. closesocket(m_ListenSocket);
  180. m_ListenSocket = INVALID_SOCKET;
  181. return dwStatus;
  182. }
  183. // Need to enable 9-wire mode before the bind():
  184. if (SOCKET_ERROR == setsockopt(m_ListenSocket,
  185. SOL_IRLMP,
  186. IRLMP_9WIRE_MODE,
  187. (const char*)&iEnable9WireMode,
  188. sizeof(iEnable9WireMode)))
  189. {
  190. dwStatus = WSAGetLastError();
  191. #ifdef DBG_ERROR
  192. WIAS_TRACE((g_hInst,"InitializeForListen(%s): setsockopt(IRLMP_9WIRE_MODE) Failed: %d",pszServiceName,dwStatus));
  193. #endif
  194. closesocket(m_ListenSocket);
  195. m_ListenSocket = INVALID_SOCKET;
  196. return dwStatus;
  197. }
  198. }
  199. // Setup the local address for the bind():
  200. memset(&AddrLocal,0,sizeof(AddrLocal));
  201. AddrLocal.irdaAddressFamily = AF_IRDA;
  202. strcpy(AddrLocal.irdaServiceName,pszServiceName);
  203. // Note: AddrLocal.irdaDeviceID ignored by server applications...
  204. if (SOCKET_ERROR == bind( m_ListenSocket,
  205. (struct sockaddr *)&AddrLocal,
  206. sizeof(AddrLocal)) )
  207. {
  208. dwStatus = WSAGetLastError();
  209. closesocket(m_ListenSocket);
  210. m_ListenSocket = INVALID_SOCKET;
  211. return dwStatus;
  212. }
  213. if (SOCKET_ERROR == listen(m_ListenSocket,2))
  214. {
  215. dwStatus = WSAGetLastError();
  216. closesocket(m_ListenSocket);
  217. m_ListenSocket = INVALID_SOCKET;
  218. return dwStatus;
  219. }
  220. #ifdef USE_IOCOMPLETION
  221. //
  222. // If this is NT, then associate the listen socket with
  223. // an IO completion port (not supported in Windows98).
  224. //
  225. hIoCP = CreateIoCompletionPort( (void*)m_ListenSocket,
  226. hIoCP,
  227. m_ListenSocket,
  228. 0 );
  229. m_hIoCompletionPort = hIoCP;
  230. #endif
  231. return dwStatus;
  232. }
  233. //------------------------------------------------------------------------
  234. // CCONNECTION::PostMoreIos()
  235. //
  236. //------------------------------------------------------------------------
  237. #if FALSE
  238. DWORD CCONNECTION::PostMoreIos( CIOPACKET *pIoPacket )
  239. {
  240. DWORD dwStatus = S_OK;
  241. LONG lNumPendingReads;
  242. while (m_lPendingReads < m_lMaxPendingReads)
  243. {
  244. if (!pIoPacket)
  245. {
  246. pIoPacket = new CIOPACKET;
  247. if (!pIoPacket)
  248. {
  249. WIAS_ERROR((g_hInst,"new CIOPACKET failed."));
  250. dwStatus = ERROR_OUTOFMEMORY;
  251. break;
  252. }
  253. dwStatus = pIoPacket->Initialize( GetKind(),
  254. GetListenSocket(),
  255. GetSocket(),
  256. GetIoCompletionPort() );
  257. }
  258. dwStatus = pIoPacket->PostIo();
  259. if (dwStatus != NO_ERROR)
  260. {
  261. WIAS_ERROR((g_hInst,"pNewIoPacket->PostIo() failed: %d\n", dwStatus ));
  262. delete pIoPacket;
  263. break;
  264. }
  265. // Increment the count of the number of pending reads on
  266. // this connection:
  267. lNumPendingReads = IncrementPendingReads();
  268. WIAS_ASSERT(g_hInst,lNumPendingReads > 0);
  269. pIoPacket = 0; // don't delete this line... this is a loop...
  270. }
  271. return dwStatus;
  272. }
  273. #endif
  274. //------------------------------------------------------------------------
  275. // CCONNECTION::SendPdu()
  276. //
  277. //------------------------------------------------------------------------
  278. DWORD CCONNECTION::SendPdu( IN SCEP_HEADER *pPdu,
  279. IN DWORD dwPduSize,
  280. OUT CIOPACKET **ppIoPacket )
  281. {
  282. DWORD dwStatus = NO_ERROR;
  283. CIOPACKET *pIoPacket = new CIOPACKET;
  284. *ppIoPacket = 0;
  285. if (!pIoPacket)
  286. {
  287. return ERROR_OUTOFMEMORY;
  288. }
  289. dwStatus = pIoPacket->Initialize( PACKET_KIND_WRITE_SOCKET,
  290. INVALID_SOCKET, // ListenSocket
  291. GetSocket(),
  292. GetIoCompletionPort() );
  293. if (dwStatus != NO_ERROR)
  294. {
  295. delete pIoPacket;
  296. return dwStatus;
  297. }
  298. dwStatus = pIoPacket->PostIoWrite(pPdu,dwPduSize,0);
  299. delete pIoPacket;
  300. return dwStatus;
  301. }
  302. //------------------------------------------------------------------------
  303. // CCONNECTION::ShutdownSocket()
  304. //
  305. //------------------------------------------------------------------------
  306. DWORD CCONNECTION::ShutdownSocket()
  307. {
  308. this->CloseSocket();
  309. return NO_ERROR;
  310. }
  311. //------------------------------------------------------------------------
  312. // CCONNECTION::CloseSocket()
  313. //
  314. //------------------------------------------------------------------------
  315. void CCONNECTION::CloseSocket()
  316. {
  317. if (m_Socket != INVALID_SOCKET)
  318. {
  319. closesocket(m_Socket);
  320. m_Socket = INVALID_SOCKET;
  321. }
  322. }
  323. //------------------------------------------------------------------------
  324. // CCONNECTION::CloseListenSocket()
  325. //
  326. //------------------------------------------------------------------------
  327. void CCONNECTION::CloseListenSocket()
  328. {
  329. if (m_ListenSocket != INVALID_SOCKET)
  330. {
  331. closesocket(m_ListenSocket);
  332. m_ListenSocket = INVALID_SOCKET;
  333. }
  334. }
  335. //------------------------------------------------------------------------
  336. // CCONNECTION::CleanupDateString()
  337. //
  338. // Make sure that the specified date string doesn't contain any slashes
  339. // which could be confused as subdirectories if the date is used as part
  340. // of a path.
  341. //------------------------------------------------------------------------
  342. void CCONNECTION::CleanupDateString( IN OUT CHAR *pszDateStr )
  343. {
  344. if (pszDateStr)
  345. {
  346. while (*pszDateStr)
  347. {
  348. if ((*pszDateStr == '/') || (*pszDateStr == '\\'))
  349. {
  350. *pszDateStr = '-';
  351. }
  352. else if (*pszDateStr < 30)
  353. {
  354. *pszDateStr = '_';
  355. }
  356. pszDateStr++;
  357. }
  358. }
  359. }
  360. //------------------------------------------------------------------------
  361. // CCONNECTION::ConstructPicturesSubDirectory()
  362. //
  363. // Generate the path for the directory where pictures will be stored
  364. // in.
  365. //
  366. // The return path string should be free'd using FreeMemory().
  367. //------------------------------------------------------------------------
  368. char *CCONNECTION::ConstructPicturesSubDirectory( IN DWORD dwExtraChars )
  369. {
  370. char *pszTempDirectory = 0;
  371. char *psz = ::GetImageDirectory();
  372. if (psz)
  373. {
  374. pszTempDirectory = (char*)AllocateMemory( strlen(psz)
  375. + dwExtraChars
  376. + 2 );
  377. }
  378. if (pszTempDirectory)
  379. {
  380. strcpy(pszTempDirectory,psz);
  381. }
  382. // Don't try to free psz !!.
  383. return pszTempDirectory;
  384. }
  385. //------------------------------------------------------------------------
  386. // CCONNECTION::ConstructFullFileName()
  387. //
  388. // Generate the path + file name that the picture will be stored
  389. // in. If dwCopyCount is zero, then its just a straight file name.
  390. // If dwCopyCount is N, then "N_" is prefixed to the file name.
  391. //------------------------------------------------------------------------
  392. CHAR *CCONNECTION::ConstructFullFileName( IN DWORD dwCopyCount )
  393. {
  394. # define MAX_DATE 64
  395. # define MAX_PREFIX 64
  396. DWORD dwLen;
  397. DWORD dwFileNameLen;
  398. DWORD dwPrefixStrLen;
  399. DWORD dwExtraChars;
  400. CHAR *pszFullFileName = 0; // Path + file name.
  401. CHAR *pszFileName = 0; // File name only.
  402. CHAR szPrefixStr[MAX_PREFIX];
  403. if (!m_pScepConnection)
  404. {
  405. return 0;
  406. }
  407. pszFileName = m_pScepConnection->GetFileName();
  408. if (!pszFileName)
  409. {
  410. return 0;
  411. }
  412. dwFileNameLen = strlen(pszFileName);
  413. if (dwCopyCount == 0)
  414. {
  415. dwExtraChars = 1 + dwFileNameLen; // Extra 1 for the "\".
  416. }
  417. else
  418. {
  419. _itoa(dwCopyCount,szPrefixStr,10);
  420. strcat(szPrefixStr,SZ_UNDERSCORE);
  421. dwPrefixStrLen = strlen(szPrefixStr);
  422. dwExtraChars = 1 + dwFileNameLen + dwPrefixStrLen;
  423. }
  424. pszFullFileName = CCONNECTION::ConstructPicturesSubDirectory(dwExtraChars);
  425. if (!pszFullFileName)
  426. {
  427. return 0;
  428. }
  429. if (dwCopyCount == 0)
  430. {
  431. strcat(pszFullFileName,SZ_SLASH);
  432. strcat(pszFullFileName,pszFileName);
  433. }
  434. else
  435. {
  436. strcat(pszFullFileName,SZ_SLASH);
  437. strcat(pszFullFileName,szPrefixStr);
  438. strcat(pszFullFileName,pszFileName);
  439. }
  440. #ifdef DBG_IO
  441. WIAS_TRACE((g_hInst,"CCONNECTION::ConstructFullFileName(): return: %s",pszFullFileName));
  442. #endif
  443. return pszFullFileName;
  444. }
  445. //------------------------------------------------------------------------
  446. // CCONNECTION::Impersonate()
  447. //
  448. //------------------------------------------------------------------------
  449. DWORD CCONNECTION::Impersonate()
  450. {
  451. DWORD dwStatus = NO_ERROR;
  452. HANDLE hToken = ::GetUserToken();
  453. if (hToken)
  454. {
  455. if (!ImpersonateLoggedOnUser(hToken))
  456. {
  457. dwStatus = GetLastError();
  458. #ifdef DBG_ERROR
  459. WIAS_ERROR((g_hInst,"IrXfer: IrTran-P: CreatePictureFile(): Impersonate Failed: %d\n",dwStatus));
  460. #endif
  461. }
  462. else
  463. {
  464. m_fImpersonating = TRUE;
  465. #ifdef DBG_IMPERSONATE
  466. WIAS_ERROR((g_hInst,"CCONNECTION::Impersonate(): Impersonate\n"));
  467. #endif
  468. }
  469. }
  470. return dwStatus;
  471. }
  472. //------------------------------------------------------------------------
  473. // CCONNECTION::RevertToSelf()
  474. //
  475. //------------------------------------------------------------------------
  476. DWORD CCONNECTION::RevertToSelf()
  477. {
  478. DWORD dwStatus = NO_ERROR;
  479. HANDLE hToken = ::GetUserToken();
  480. if ((hToken) && (m_fImpersonating))
  481. {
  482. ::RevertToSelf();
  483. m_fImpersonating = FALSE;
  484. }
  485. return dwStatus;
  486. }
  487. //------------------------------------------------------------------------
  488. // CCONNECTION::CreatePictureFile()
  489. //
  490. //------------------------------------------------------------------------
  491. DWORD CCONNECTION::CreatePictureFile()
  492. {
  493. DWORD dwStatus = NO_ERROR;
  494. CHAR *pszFile;
  495. CHAR *pszPathPlusFileName = 0;
  496. DWORD dwFlags = FILE_ATTRIBUTE_NORMAL;
  497. // Make sure that the counters start at zero:
  498. m_dwUpfBytes = 0;
  499. m_dwBytesWritten = 0;
  500. // See if we already have an image file open, if yes then
  501. // close it.
  502. if (m_hFile != INVALID_HANDLE_VALUE)
  503. {
  504. CloseHandle(m_hFile);
  505. }
  506. // Get the full path + name for the file we will create.
  507. // Note, that ConstructFullFileName() may create a subdirectory,
  508. // so it needs to be done after the impersonation...
  509. // This is important if we have a remoted \My Documents\
  510. // directory.
  511. DWORD dwCopyCount;
  512. for (dwCopyCount=0; dwCopyCount<=MAX_COPYOF_TRIES; dwCopyCount++)
  513. {
  514. pszPathPlusFileName = ConstructFullFileName(dwCopyCount);
  515. if (!pszPathPlusFileName)
  516. {
  517. return ERROR_SCEP_CANT_CREATE_FILE;
  518. }
  519. //
  520. // Try to create new image (JPEG) file:
  521. //
  522. m_hFile = CreateFile( pszPathPlusFileName,
  523. GENERIC_WRITE,
  524. FILE_SHARE_READ, // Share mode.
  525. 0, // Security attr (BUGBUG).
  526. CREATE_NEW, // Open mode.
  527. dwFlags, // Attributes.
  528. 0 ); // Template file (none).
  529. if (m_hFile != INVALID_HANDLE_VALUE)
  530. {
  531. // This is the success exit point.
  532. m_pszPathPlusFileName = pszPathPlusFileName;
  533. break;
  534. }
  535. else
  536. {
  537. dwStatus = GetLastError();
  538. if (dwStatus != ERROR_FILE_EXISTS)
  539. {
  540. #ifdef DBG_TARGET_DIR
  541. WIAS_ERROR((g_hInst,"CCONNECTION::CreatePictureFile(): CreateFile(): %s Failed: %d",pszPathPlusFileName,dwStatus));
  542. #endif
  543. FreeMemory(pszPathPlusFileName);
  544. break;
  545. }
  546. // If we get here, then then a picture file by that name
  547. // alreay exists, so try again...
  548. FreeMemory(pszPathPlusFileName);
  549. }
  550. }
  551. return dwStatus;
  552. }
  553. //------------------------------------------------------------------------
  554. // CCONNECTION::SetPictureFileTime()
  555. //
  556. //------------------------------------------------------------------------
  557. DWORD CCONNECTION::SetPictureFileTime( IN FILETIME *pFileTime )
  558. {
  559. DWORD dwStatus = NO_ERROR;
  560. if (!pFileTime)
  561. {
  562. return dwStatus; // Empty case, no time to set.
  563. }
  564. if (!SetFileTime(m_hFile,pFileTime,pFileTime,pFileTime))
  565. {
  566. dwStatus = GetLastError();
  567. WIAS_ERROR((g_hInst,"IrTranP: SetFileTime() Failed: %d",dwStatus));
  568. }
  569. return dwStatus;
  570. }
  571. //------------------------------------------------------------------------
  572. // CCONNECTION::WritePictureFile()
  573. //
  574. //------------------------------------------------------------------------
  575. DWORD CCONNECTION::WritePictureFile( IN UCHAR *pBuffer,
  576. IN DWORD dwBufferSize,
  577. OUT CIOPACKET **ppIoPacket )
  578. {
  579. DWORD dwStatus = NO_ERROR;
  580. DWORD dwOffset = m_dwBytesWritten;
  581. DWORD dwBytesToWrite;
  582. LONG lPendingWrites;
  583. *ppIoPacket = 0;
  584. CIOPACKET *pIoPacket = new CIOPACKET;
  585. if (!pIoPacket)
  586. {
  587. return ERROR_OUTOFMEMORY;
  588. }
  589. dwStatus = pIoPacket->Initialize( PACKET_KIND_WRITE_FILE,
  590. INVALID_SOCKET, // ListenSocket
  591. INVALID_SOCKET, // Camera...
  592. GetIoCompletionPort() );
  593. if (dwStatus != NO_ERROR)
  594. {
  595. delete pIoPacket;
  596. return dwStatus;
  597. }
  598. pIoPacket->SetFileHandle(m_hFile);
  599. //
  600. // If we are writing just the JPEG image out of the UPF file,
  601. // then we don't want to write the first m_dwJpegOffset bytes
  602. // of the UPF file.
  603. //
  604. if ((m_dwUpfBytes >= m_dwJpegOffset) || (m_fSaveAsUPF))
  605. {
  606. dwBytesToWrite = dwBufferSize;
  607. }
  608. else if ((m_dwUpfBytes + dwBufferSize) > m_dwJpegOffset)
  609. {
  610. dwBytesToWrite = (m_dwUpfBytes + dwBufferSize) - m_dwJpegOffset;
  611. for (DWORD i=0; i<dwBytesToWrite; i++)
  612. {
  613. pBuffer[i] = pBuffer[i+m_dwJpegOffset-m_dwUpfBytes];
  614. }
  615. }
  616. else
  617. {
  618. dwBytesToWrite = 0;
  619. }
  620. //
  621. // When we start writing the JPEG file we want to cut off the
  622. // file save writes once we've written out the m_dwJpegSize
  623. // bytes that are the JPEG image inside of the UPF file.
  624. //
  625. if (!m_fSaveAsUPF)
  626. {
  627. if (m_dwBytesWritten < m_dwJpegSize)
  628. {
  629. if ((m_dwBytesWritten+dwBytesToWrite) > m_dwJpegSize)
  630. {
  631. dwBytesToWrite = m_dwJpegSize - m_dwBytesWritten;
  632. }
  633. }
  634. else
  635. {
  636. dwBytesToWrite = 0;
  637. }
  638. }
  639. //
  640. // If there are bytes to actually write, then let's do it.
  641. //
  642. if (dwBytesToWrite > 0)
  643. {
  644. dwStatus = pIoPacket->PostIoWrite(pBuffer,dwBytesToWrite,dwOffset);
  645. if (dwStatus == NO_ERROR)
  646. {
  647. lPendingWrites = IncrementPendingWrites();
  648. WIAS_ASSERT(g_hInst, lPendingWrites > 0 );
  649. m_dwBytesWritten += dwBytesToWrite;
  650. *ppIoPacket = pIoPacket;
  651. }
  652. }
  653. delete pIoPacket;
  654. m_dwUpfBytes += dwBufferSize;
  655. return dwStatus;
  656. }
  657. //------------------------------------------------------------------------
  658. // CCONNECTION::DeletePictureFile()
  659. //
  660. //------------------------------------------------------------------------
  661. DWORD CCONNECTION::DeletePictureFile()
  662. {
  663. DWORD dwStatus = NO_ERROR;
  664. if (m_hFile == INVALID_HANDLE_VALUE)
  665. {
  666. return NO_ERROR;
  667. }
  668. CloseHandle(m_hFile);
  669. m_hFile = INVALID_HANDLE_VALUE;
  670. if (m_pszPathPlusFileName)
  671. {
  672. DeleteFile(m_pszPathPlusFileName);
  673. }
  674. return dwStatus;
  675. }
  676. //------------------------------------------------------------------------
  677. // CCONNECTION::ClosePictureFile()
  678. //
  679. //------------------------------------------------------------------------
  680. DWORD CCONNECTION::ClosePictureFile()
  681. {
  682. DWORD dwStatus = NO_ERROR;
  683. #if FALSE
  684. if (m_pszPathPlusFileName)
  685. {
  686. FreeMemory(m_pszPathPlusFileName);
  687. m_pszPathPlusFileName = 0;
  688. }
  689. #endif
  690. if (m_hFile != INVALID_HANDLE_VALUE)
  691. {
  692. if (!CloseHandle(m_hFile))
  693. {
  694. dwStatus = GetLastError();
  695. }
  696. m_hFile = INVALID_HANDLE_VALUE;
  697. }
  698. return dwStatus;
  699. }
  700. //------------------------------------------------------------------------
  701. // CCONNECTION::IncompleteFile()
  702. //
  703. // Check to see if we have a complete picture file, if yes, then return
  704. // FALSE, else return TRUE.
  705. //------------------------------------------------------------------------
  706. BOOL CCONNECTION::IncompleteFile()
  707. {
  708. BOOL fIncomplete = FALSE;
  709. if (m_fSaveAsUPF)
  710. {
  711. // Note: currently save the .UPF file, even if its incomplete.
  712. // This file mode is set in the registry and is for testing
  713. // only...
  714. fIncomplete = FALSE;
  715. }
  716. else if (!m_fReceiveComplete)
  717. {
  718. fIncomplete = (m_dwBytesWritten < m_dwJpegSize);
  719. }
  720. return fIncomplete;
  721. }
  722. //------------------------------------------------------------------------
  723. // CCONNECTION::StartProgress()
  724. //
  725. // Startup the progress bar for the incomming JPEG.
  726. //------------------------------------------------------------------------
  727. DWORD CCONNECTION::StartProgress()
  728. {
  729. DWORD dwStatus = 0;
  730. if (!m_pIrProgress)
  731. {
  732. m_pIrProgress = new CIrProgress;
  733. if (m_pIrProgress)
  734. {
  735. dwStatus = m_pIrProgress->Initialize(g_hInst,IDR_TRANSFER_AVI);
  736. }
  737. else
  738. {
  739. return E_OUTOFMEMORY;
  740. }
  741. }
  742. if (m_pIrProgress)
  743. {
  744. dwStatus = m_pIrProgress->StartProgressDialog();
  745. }
  746. return dwStatus;
  747. }
  748. //------------------------------------------------------------------------
  749. // CCONNECTION::UpdateProgress()
  750. //
  751. // Update the progress bar's completion display.
  752. //------------------------------------------------------------------------
  753. DWORD CCONNECTION::UpdateProgress()
  754. {
  755. DWORD dwStatus = 0;
  756. if (m_pIrProgress)
  757. {
  758. dwStatus = m_pIrProgress->UpdateProgressDialog( m_dwBytesWritten,
  759. m_dwJpegSize );
  760. }
  761. return dwStatus;
  762. }
  763. //------------------------------------------------------------------------
  764. // CCONNECTION::EndProgress()
  765. //
  766. // File transfer complete, hide the progress bar.
  767. //------------------------------------------------------------------------
  768. DWORD CCONNECTION::EndProgress()
  769. {
  770. DWORD dwStatus = 0;
  771. if (m_pIrProgress)
  772. {
  773. dwStatus = m_pIrProgress->EndProgressDialog();
  774. delete m_pIrProgress;
  775. m_pIrProgress = NULL;
  776. }
  777. return dwStatus;
  778. }
  779. //************************************************************************
  780. //------------------------------------------------------------------------
  781. // CCONNECTION_MAP::CCONNECTION_MAP()
  782. //
  783. //------------------------------------------------------------------------
  784. CCONNECTION_MAP::CCONNECTION_MAP()
  785. {
  786. m_dwMapSize = 0;
  787. m_pMap = 0;
  788. ZeroMemory(&m_cs, sizeof(m_cs));
  789. }
  790. //------------------------------------------------------------------------
  791. // CCONNECTION_MAP::~CCONNECTION_MAP()
  792. //
  793. //------------------------------------------------------------------------
  794. CCONNECTION_MAP::~CCONNECTION_MAP()
  795. {
  796. if (m_pMap)
  797. {
  798. DeleteCriticalSection(&m_cs);
  799. FreeMemory(m_pMap);
  800. }
  801. }
  802. //------------------------------------------------------------------------
  803. // CCONNECTION_MAP::operator new()
  804. //
  805. //------------------------------------------------------------------------
  806. void *CCONNECTION_MAP::operator new( IN size_t Size )
  807. {
  808. void *pObj = AllocateMemory(Size);
  809. return pObj;
  810. }
  811. //------------------------------------------------------------------------
  812. // CCONNECTION_MAP::operator delete()
  813. //
  814. //------------------------------------------------------------------------
  815. void CCONNECTION_MAP::operator delete( IN void *pObj,
  816. IN size_t Size )
  817. {
  818. if (pObj)
  819. {
  820. DWORD dwStatus = FreeMemory(pObj);
  821. }
  822. }
  823. //------------------------------------------------------------------------
  824. // CCONNECTION_MAP::Initialize()
  825. //
  826. //------------------------------------------------------------------------
  827. BOOL CCONNECTION_MAP::Initialize( IN DWORD dwNewMapSize )
  828. {
  829. if (!dwNewMapSize)
  830. {
  831. return FALSE;
  832. }
  833. if (!m_dwMapSize)
  834. {
  835. m_pMap = (CONNECTION_MAP_ENTRY*)AllocateMemory( dwNewMapSize*sizeof(CONNECTION_MAP_ENTRY) );
  836. if (!m_pMap)
  837. {
  838. return FALSE;
  839. }
  840. __try
  841. {
  842. if(!InitializeCriticalSectionAndSpinCount(&m_cs, MINLONG))
  843. {
  844. FreeMemory(m_pMap);
  845. m_pMap = NULL;
  846. return FALSE;
  847. }
  848. }
  849. __except(EXCEPTION_EXECUTE_HANDLER)
  850. {
  851. FreeMemory(m_pMap);
  852. m_pMap = NULL;
  853. return FALSE;
  854. }
  855. m_dwMapSize = dwNewMapSize;
  856. memset(m_pMap,0,m_dwMapSize*sizeof(CONNECTION_MAP_ENTRY));
  857. for (DWORD i=0; i<m_dwMapSize; i++)
  858. {
  859. m_pMap[i].Socket = INVALID_SOCKET;
  860. }
  861. }
  862. return TRUE;
  863. }
  864. //------------------------------------------------------------------------
  865. // CCONNECTION_MAP::Lookup()
  866. //
  867. //------------------------------------------------------------------------
  868. CCONNECTION *CCONNECTION_MAP::Lookup( IN SOCKET Socket )
  869. {
  870. DWORD i;
  871. EnterCriticalSection(&m_cs);
  872. for (i=0; i<m_dwMapSize; i++)
  873. {
  874. if (m_pMap[i].Socket == Socket)
  875. {
  876. LeaveCriticalSection(&m_cs);
  877. return m_pMap[i].pConnection;
  878. }
  879. }
  880. LeaveCriticalSection(&m_cs);
  881. return 0;
  882. }
  883. //------------------------------------------------------------------------
  884. // CCONNECTION_MAP::LookupByServiceName()
  885. //
  886. //------------------------------------------------------------------------
  887. CCONNECTION *CCONNECTION_MAP::LookupByServiceName( IN char *pszServiceName )
  888. {
  889. DWORD i;
  890. CCONNECTION *pConnection;
  891. EnterCriticalSection(&m_cs);
  892. for (i=0; i<m_dwMapSize; i++)
  893. {
  894. pConnection = m_pMap[i].pConnection;
  895. if ( (pConnection)
  896. && (pConnection->GetServiceName())
  897. && (!strcmp(pConnection->GetServiceName(),pszServiceName)))
  898. {
  899. LeaveCriticalSection(&m_cs);
  900. return pConnection;
  901. }
  902. }
  903. LeaveCriticalSection(&m_cs);
  904. return 0;
  905. }
  906. //------------------------------------------------------------------------
  907. // CCONNECTION_MAP::Add()
  908. //
  909. //------------------------------------------------------------------------
  910. BOOL CCONNECTION_MAP::Add( IN CCONNECTION *pConnection,
  911. IN SOCKET Socket )
  912. {
  913. DWORD i;
  914. // Only add entries that look valid...
  915. if ((Socket == 0)||(Socket==INVALID_SOCKET)||(pConnection == 0))
  916. {
  917. return FALSE;
  918. }
  919. EnterCriticalSection(&m_cs);
  920. // Look for an empty place in the table:
  921. for (i=0; i<m_dwMapSize; i++)
  922. {
  923. if (m_pMap[i].Socket == INVALID_SOCKET)
  924. {
  925. m_pMap[i].Socket = Socket;
  926. m_pMap[i].pConnection = pConnection;
  927. LeaveCriticalSection(&m_cs);
  928. return TRUE;
  929. }
  930. }
  931. // The table is full, expand it...
  932. DWORD dwNewMapSize = 3*m_dwMapSize/2; // 50% bigger.
  933. CONNECTION_MAP_ENTRY *pMap = (CONNECTION_MAP_ENTRY*)AllocateMemory( dwNewMapSize*sizeof(CONNECTION_MAP_ENTRY) );
  934. if (!pMap)
  935. {
  936. LeaveCriticalSection(&m_cs);
  937. return FALSE; // Out of memory...
  938. }
  939. memset(pMap,0,dwNewMapSize*sizeof(CONNECTION_MAP_ENTRY));
  940. for (i=0; i<dwNewMapSize; i++)
  941. {
  942. pMap[i].Socket = INVALID_SOCKET;
  943. }
  944. for (i=0; i<m_dwMapSize; i++)
  945. {
  946. pMap[i].Socket = m_pMap[i].Socket;
  947. pMap[i].pConnection = m_pMap[i].pConnection;
  948. }
  949. pMap[i].Socket = Socket;
  950. pMap[i].pConnection = pConnection;
  951. FreeMemory(m_pMap);
  952. m_pMap = pMap;
  953. m_dwMapSize = dwNewMapSize;
  954. LeaveCriticalSection(&m_cs);
  955. return TRUE;
  956. }
  957. //------------------------------------------------------------------------
  958. // CCONNECTION_MAP::Remove()
  959. //
  960. //------------------------------------------------------------------------
  961. CCONNECTION *CCONNECTION_MAP::Remove( IN SOCKET Socket )
  962. {
  963. DWORD i;
  964. CCONNECTION *pConnection;
  965. EnterCriticalSection(&m_cs);
  966. for (i=0; i<m_dwMapSize; i++)
  967. {
  968. if (m_pMap[i].Socket == Socket)
  969. {
  970. pConnection = m_pMap[i].pConnection;
  971. m_pMap[i].Socket = INVALID_SOCKET;
  972. m_pMap[i].pConnection = 0;
  973. LeaveCriticalSection(&m_cs);
  974. return pConnection;
  975. }
  976. }
  977. LeaveCriticalSection(&m_cs);
  978. return 0;
  979. }
  980. //------------------------------------------------------------------------
  981. // CCONNECTION_MAP::RemoveConnection()
  982. //
  983. //------------------------------------------------------------------------
  984. CCONNECTION *CCONNECTION_MAP::RemoveConnection( IN CCONNECTION *pConnection )
  985. {
  986. DWORD i;
  987. EnterCriticalSection(&m_cs);
  988. for (i=0; i<m_dwMapSize; i++)
  989. {
  990. if (m_pMap[i].pConnection == pConnection)
  991. {
  992. m_pMap[i].Socket = INVALID_SOCKET;
  993. m_pMap[i].pConnection = 0;
  994. LeaveCriticalSection(&m_cs);
  995. return pConnection;
  996. }
  997. }
  998. LeaveCriticalSection(&m_cs);
  999. return 0;
  1000. }
  1001. //------------------------------------------------------------------------
  1002. // CCONNECTION_MAP::RemoveNext()
  1003. //
  1004. // Walk through the connection map and get the next entry, remove the
  1005. // entry from the map as well.
  1006. //------------------------------------------------------------------------
  1007. CCONNECTION *CCONNECTION_MAP::RemoveNext()
  1008. {
  1009. DWORD i;
  1010. CCONNECTION *pConnection;
  1011. EnterCriticalSection(&m_cs);
  1012. for (i=0; i<m_dwMapSize; i++)
  1013. {
  1014. if (m_pMap[i].Socket)
  1015. {
  1016. pConnection = m_pMap[i].pConnection;
  1017. m_pMap[i].Socket = INVALID_SOCKET;
  1018. m_pMap[i].pConnection = 0;
  1019. LeaveCriticalSection(&m_cs);
  1020. return pConnection;
  1021. }
  1022. }
  1023. LeaveCriticalSection(&m_cs);
  1024. return 0;
  1025. }
  1026. //------------------------------------------------------------------------
  1027. // CCONNECTION_MAP::ReturnNext()
  1028. //
  1029. // Walk through the connection map returning the next entry. To start at
  1030. // the "begining", pass in state equal zero. When you get to the end of
  1031. // the list of connections, return NULL;
  1032. //------------------------------------------------------------------------
  1033. CCONNECTION *CCONNECTION_MAP::ReturnNext( IN OUT DWORD *pdwState )
  1034. {
  1035. CCONNECTION *pConnection = NULL;
  1036. EnterCriticalSection(&m_cs);
  1037. if (*pdwState >= m_dwMapSize)
  1038. {
  1039. LeaveCriticalSection(&m_cs);
  1040. return NULL;
  1041. }
  1042. while ((pConnection == NULL) && (*pdwState < m_dwMapSize))
  1043. {
  1044. pConnection = m_pMap[(*pdwState)++].pConnection;
  1045. }
  1046. LeaveCriticalSection(&m_cs);
  1047. return pConnection;
  1048. }
  1049. //------------------------------------------------------------------------
  1050. // CCONNECTION_MAP::ReturnNextSocket()
  1051. //
  1052. // Walk through the connection map returning the SOCKET associated with
  1053. // the next entry. To start at the "begining", pass in state equal zero.
  1054. // When you get to the end of the list of connections, return
  1055. // INVALID_SOCKET.
  1056. //------------------------------------------------------------------------
  1057. SOCKET CCONNECTION_MAP::ReturnNextSocket( IN OUT DWORD *pdwState )
  1058. {
  1059. SOCKET Socket = INVALID_SOCKET;
  1060. EnterCriticalSection(&m_cs);
  1061. if (*pdwState >= m_dwMapSize)
  1062. {
  1063. LeaveCriticalSection(&m_cs);
  1064. return INVALID_SOCKET;
  1065. }
  1066. while ((Socket == INVALID_SOCKET) && (*pdwState < m_dwMapSize))
  1067. {
  1068. Socket = m_pMap[(*pdwState)++].Socket;
  1069. }
  1070. LeaveCriticalSection(&m_cs);
  1071. return Socket;
  1072. }