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.

1347 lines
30 KiB

  1. /* File: D:\WACKER\tdll\sf.c (Created: 27-Nov-1993)
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 16 $
  7. * $Date: 3/15/02 12:27p $
  8. */
  9. #include <windows.h>
  10. #include <shlobj.h>
  11. #pragma hdrstop
  12. #include <stdio.h>
  13. #include <sys\types.h>
  14. #include <sys\stat.h>
  15. #include "stdtyp.h"
  16. #include "tdll.h"
  17. #include "htchar.h"
  18. #include "sf.h"
  19. #include "mc.h"
  20. typedef int int32;
  21. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  22. *
  23. * DATA SECTION
  24. *
  25. * This section contains all of the static data that the DLL uses. Once this
  26. * data is exhausted, the DLL can do no more. It just returns errors. This
  27. * means that it is important to close or release any and all session files
  28. * that get opened.
  29. *
  30. */
  31. struct stDllSessionFileIndexItem
  32. {
  33. int32 uIndex; /* Index of the item */
  34. int32 dwSize; /* Size of the item */
  35. int32 dwOffset; /* Offset into data block of the item */
  36. };
  37. typedef struct stDllSessionFileIndexItem stDSII;
  38. typedef stDSII *pstDSII;
  39. struct stDllSessionFilePointer
  40. {
  41. int uBusy; /* TRUE means item is in use */
  42. int fOpen; /* TRUE means open session file */
  43. int uChanged; /* TRUE means something is different */
  44. TCHAR *hFilename; /* Memory containing the file name */
  45. /* These make up the index */
  46. int uItemCount; /* Current items in the index */
  47. int uItemsAlloc; /* Max items in current space */
  48. pstDSII hIndex; /* Memory allocated for index */
  49. /* This is the data segment */
  50. int dwDataUsed; /* Amount used in data block */
  51. int dwDataSize; /* Current sizeof the data block */
  52. BYTE *hData; /* Memory allocated for file data */
  53. };
  54. typedef struct stDllSessionFilePointer stDSFP;
  55. typedef stDSFP *pstDSFP;
  56. #define ROUND_UP(x) ((x+0xFFFL)&(~0x0FFFL))
  57. // used for testing #define ROUND_UP(x) ((x+0x3F)&(~0x03F))
  58. #define SESS_FILE_MAX 64
  59. static stDSFP asSessionFiles[SESS_FILE_MAX];
  60. #define HDR_SIZE 256
  61. TCHAR pszHdr[HDR_SIZE] =
  62. {
  63. TEXT("HyperTerminal 1.0 -- HyperTerminal data file\r\n")
  64. TEXT("Please do not attempt to modify this file directly.\r\n")
  65. TEXT("\r\n\r\n")
  66. TEXT("\x1A")
  67. };
  68. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  69. * FUNCTION: sfAddToIndex
  70. *
  71. * DESCRIPTION:
  72. *
  73. * ARGUEMENTS:
  74. *
  75. * RETURNS:
  76. * The offset of the item in the index array, or -1.
  77. */
  78. int32 sfAddToIndex(const int uNdx,
  79. const int32 sID,
  80. const int32 dwSZ,
  81. const int32 dwOffset)
  82. {
  83. int nRv = -1;
  84. int nCnt;
  85. int low, mid, high;
  86. int found;
  87. pstDSFP pD;
  88. pstDSII pI;
  89. pstDSII pIx;
  90. pstDSII pIy;
  91. pD = &asSessionFiles[uNdx];
  92. if (pD->uItemCount >= pD->uItemsAlloc)
  93. {
  94. #if defined(DEBUG_OUTPUT)
  95. OutputDebugString("Index expanded\r\n");
  96. #endif
  97. /*
  98. * We need to get a bigger chunk of memory
  99. */
  100. if (pD->hIndex == 0)
  101. {
  102. pD->uItemsAlloc = 64;
  103. pD->hIndex = (pstDSII)malloc(sizeof(stDSII) * 64);
  104. }
  105. else
  106. {
  107. int newSize = pD->uItemsAlloc * 2;
  108. stDSII * pTemphIndex = (pstDSII)
  109. realloc(pD->hIndex, (size_t)newSize * sizeof(stDSII));
  110. if (pTemphIndex == NULL)
  111. {
  112. return SF_ERR_MEMORY_ERROR;
  113. }
  114. else
  115. {
  116. pD->uItemsAlloc = newSize;
  117. pD->hIndex = pTemphIndex;
  118. }
  119. }
  120. }
  121. if (pD->hData == 0)
  122. {
  123. pD->hData = (BYTE *)malloc(ROUND_UP(4096));
  124. memset(pD->hData, 0, HDR_SIZE);
  125. pD->dwDataSize = ROUND_UP(4096);
  126. pD->dwDataUsed = HDR_SIZE;
  127. }
  128. /*
  129. * Find where the item goes
  130. */
  131. pI = pD->hIndex;
  132. found = FALSE;
  133. pIx = 0;
  134. low = 0;
  135. high = pD->uItemCount - 1;
  136. mid = high/2;
  137. if (pD->uItemCount > 0)
  138. {
  139. while (low <= high)
  140. {
  141. mid = (low + high) / 2;
  142. pIx = pI + mid;
  143. if (sID < pIx->uIndex)
  144. {
  145. high = mid - 1;
  146. }
  147. else if (sID > pIx->uIndex)
  148. {
  149. low = mid + 1;
  150. }
  151. else
  152. {
  153. /* found a match */
  154. found = TRUE;
  155. break;
  156. }
  157. }
  158. }
  159. if (found)
  160. {
  161. if (dwSZ != 0)
  162. {
  163. /*
  164. * Special case. Preserve the old values so that we can
  165. * adjust the data section for the replacement value.
  166. */
  167. pIx->dwSize = dwSZ;
  168. pIx->dwOffset = dwOffset;
  169. }
  170. nRv = mid;
  171. }
  172. else
  173. {
  174. /*
  175. * The problem with a binary search is that it is unclear where
  176. * you are if no match occurs. So we do it the old way.
  177. */
  178. pIx = pI;
  179. nCnt = 0;
  180. for (;;)
  181. {
  182. /* TODO: switch to binary search */
  183. if (nCnt >= pD->uItemCount)
  184. {
  185. /*
  186. * We have gone past the end of the list
  187. */
  188. pIx->uIndex = sID;
  189. pIx->dwSize = dwSZ;
  190. pIx->dwOffset = dwOffset;
  191. nRv = nCnt;
  192. break;
  193. }
  194. else if (pIx->uIndex >= sID)
  195. {
  196. if (pIx->uIndex > sID)
  197. {
  198. /*
  199. * Slide the remaining items down by one
  200. */
  201. pIy = pI + pD->uItemCount;
  202. while (pIy > pIx)
  203. {
  204. *pIy = *(pIy - 1);
  205. pIy -= 1;
  206. }
  207. #if 0
  208. /* Don, would this work better? */
  209. _fmemmove(pIx+1, pIx,
  210. (pD->uItemCount - nCnt) * sizeof(stDSII));
  211. #endif
  212. pIx->uIndex = sID;
  213. pIx->dwSize = dwSZ;
  214. pIx->dwOffset = dwOffset;
  215. }
  216. else /* == */
  217. {
  218. if (dwSZ != 0)
  219. {
  220. /*
  221. * Special case. Preserve the old values so that we can
  222. * adjust the data section for the replacement value.
  223. */
  224. pIx->dwSize = dwSZ;
  225. pIx->dwOffset = dwOffset;
  226. }
  227. pD->uItemCount -= 1;
  228. }
  229. nRv = (int)(pIx - pI);
  230. break;
  231. }
  232. pIx += 1;
  233. nCnt += 1;
  234. }
  235. pD->uItemCount += 1;
  236. }
  237. return nRv;
  238. }
  239. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  240. * FUNCTION:
  241. * CreateSysFileHdl
  242. *
  243. * DESCRIPTION:
  244. * Creates a session file handle
  245. *
  246. * ARGUMENTS:
  247. * none
  248. *
  249. * RETURNS:
  250. * SF_HANDLE or < 0 for error
  251. *
  252. */
  253. SF_HANDLE CreateSysFileHdl(void)
  254. {
  255. int uNdx;
  256. for (uNdx = 0; uNdx < SESS_FILE_MAX; uNdx += 1)
  257. {
  258. /*
  259. * See if an unused slot is available
  260. */
  261. if (asSessionFiles[uNdx].uBusy == 0)
  262. {
  263. memset(&asSessionFiles[uNdx], 0, sizeof(stDSFP));
  264. asSessionFiles[uNdx].uBusy = TRUE;
  265. return (uNdx + 1);
  266. }
  267. }
  268. return SF_ERR_BAD_PARAMETER;
  269. }
  270. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  271. * FUNCTION: sfOpenSessionFile
  272. *
  273. * DESCRIPTION:
  274. * This function is called to build an in memory data structure that
  275. * represents the data currently in a session file. If the file specified
  276. * is not a valid session file, an error is returned.
  277. *
  278. * ARGUEMENTS:
  279. * TCHAR *pszName -- the name of the session file.
  280. *
  281. * RETURNS:
  282. * 0 or an error code < 0;
  283. */
  284. int sfOpenSessionFile(const SF_HANDLE sF, const TCHAR *pszName)
  285. {
  286. int uRv = 0;
  287. int uNdx = sF - 1;
  288. unsigned long uSize, uSize1;
  289. TCHAR *pszStr = NULL;
  290. TCHAR *pszPtr = NULL;
  291. HANDLE hFile;
  292. int sID, sOldID;
  293. int32 dwSZ;
  294. int nOrderOK;
  295. DWORD dw;
  296. if (uNdx >= SESS_FILE_MAX)
  297. {
  298. uRv = SF_ERR_BAD_PARAMETER;
  299. goto OSFexit;
  300. }
  301. if (asSessionFiles[uNdx].uBusy == 0)
  302. {
  303. uRv = SF_ERR_BAD_PARAMETER;
  304. goto OSFexit;
  305. }
  306. if (asSessionFiles[uNdx].fOpen)
  307. {
  308. uRv = SF_ERR_FILE_ACCESS;
  309. goto OSFexit;
  310. }
  311. if (pszName && (StrCharGetStrLength(pszName) > 0))
  312. {
  313. int nRv = -1;
  314. pstDSFP pD;
  315. pstDSII pI;
  316. pstDSII pIx;
  317. /*
  318. * Do everything that can be done with a name
  319. */
  320. asSessionFiles[uNdx].hFilename = (TCHAR *)malloc(FNAME_LEN * sizeof(TCHAR));
  321. if (asSessionFiles[uNdx].hFilename == NULL)
  322. goto OSFexit;
  323. pszStr = asSessionFiles[uNdx].hFilename;
  324. TCHAR_Fill(pszStr, TEXT('\0'), FNAME_LEN);
  325. StrCharCopyN(pszStr, (LPTSTR)pszName, FNAME_LEN);
  326. pszStr = NULL;
  327. /*
  328. * Try to open file. If we can then proceed
  329. */
  330. hFile = CreateFile(pszName, GENERIC_READ, 0, NULL,
  331. OPEN_EXISTING, 0, NULL);
  332. /*
  333. * Get the size of the file
  334. */
  335. if (hFile == INVALID_HANDLE_VALUE)
  336. {
  337. asSessionFiles[uNdx].fOpen = TRUE;
  338. uRv = SF_ERR_FILE_ACCESS;
  339. return uRv;
  340. }
  341. else
  342. {
  343. /*
  344. * Allocate a data block
  345. */
  346. asSessionFiles[uNdx].fOpen = TRUE;
  347. uSize = GetFileSize(hFile, &dw);
  348. uSize = ROUND_UP(uSize);
  349. asSessionFiles[uNdx].dwDataSize = (int)uSize;
  350. asSessionFiles[uNdx].dwDataUsed = 0;
  351. asSessionFiles[uNdx].hData = (BYTE *)malloc(uSize);
  352. if (asSessionFiles[uNdx].hData == 0)
  353. {
  354. uRv = SF_ERR_MEMORY_ERROR;
  355. goto OSFexit;
  356. }
  357. pszStr = (TCHAR *)asSessionFiles[uNdx].hData;
  358. pszPtr = pszStr;
  359. memset(pszStr, 0, uSize * sizeof(TCHAR));
  360. /*
  361. * Read in the header and check it
  362. */
  363. //fread(pszPtr, 1, HDR_SIZE, f);
  364. if(HDR_SIZE > uSize)
  365. {
  366. CloseHandle(hFile);
  367. uRv = SF_ERR_FILE_FORMAT;
  368. goto OSFexit;
  369. }
  370. if (ReadFile(hFile, pszPtr, HDR_SIZE * sizeof(TCHAR), &dw, 0) == FALSE)
  371. {
  372. CloseHandle(hFile);
  373. uRv = SF_ERR_FILE_ACCESS;
  374. goto OSFexit;
  375. }
  376. if (memcmp(pszPtr, pszHdr, 10 * sizeof(TCHAR)) != 0)
  377. {
  378. CloseHandle(hFile);
  379. uRv = SF_ERR_FILE_FORMAT;
  380. goto OSFexit;
  381. }
  382. pszPtr += HDR_SIZE;
  383. asSessionFiles[uNdx].dwDataUsed += HDR_SIZE;
  384. /*
  385. * Initialize the index
  386. */
  387. asSessionFiles[uNdx].uItemCount = 0;
  388. asSessionFiles[uNdx].uItemsAlloc = 64;
  389. uSize1 = sizeof(stDSII) * 64;
  390. asSessionFiles[uNdx].hIndex = (pstDSII)malloc(uSize1);
  391. if (asSessionFiles[uNdx].hIndex == (pstDSII)0)
  392. {
  393. CloseHandle(hFile);
  394. uRv = SF_ERR_MEMORY_ERROR;
  395. goto OSFexit;
  396. }
  397. /*
  398. * Read in the data items and add them to to structure
  399. * The file is in the format:
  400. *
  401. * USHORT index
  402. * DWORD dwSize
  403. * CHAR * size
  404. */
  405. pD = &asSessionFiles[uNdx];
  406. pI = pD->hIndex;
  407. nOrderOK = TRUE;
  408. sOldID = 0;
  409. for (;;)
  410. {
  411. sID = 0;
  412. dwSZ = -1;
  413. if (ReadFile(hFile, &sID, sizeof(SHORT), &dw, 0) == FALSE)
  414. {
  415. CloseHandle(hFile);
  416. uRv = SF_ERR_FILE_ACCESS;
  417. goto OSFexit;
  418. }
  419. if (ReadFile(hFile, &dwSZ, sizeof(DWORD), &dw, 0) == FALSE)
  420. {
  421. CloseHandle(hFile);
  422. uRv = SF_ERR_FILE_ACCESS;
  423. goto OSFexit;
  424. }
  425. if ((sID == 0) && (dwSZ == -1))
  426. break;
  427. if ((sID == 0) && (dwSZ == 0))
  428. continue;
  429. if (sOldID > sID)
  430. {
  431. nOrderOK = FALSE;
  432. pI = (pstDSII)0;
  433. pszStr = NULL;
  434. }
  435. sOldID = sID; /* For next time around */
  436. #if defined(DEBUG_OUTPUT)
  437. wsprintf(acBuffer,
  438. "r %c %d(0x%x) %d\r\n",
  439. nOrderOK ? 'a' : 'i',
  440. sID, sID, dwSZ);
  441. OutputDebugString(acBuffer);
  442. #endif
  443. if (nOrderOK)
  444. {
  445. // Do it inline
  446. if (pD->uItemCount >= pD->uItemsAlloc)
  447. {
  448. #if defined(DEBUG_OUTPUT)
  449. OutputDebugString("Index expanded\r\n");
  450. #endif
  451. /*
  452. * We need to get a bigger chunk of memory
  453. */
  454. if (pD->hIndex == (pstDSII)0)
  455. {
  456. pD->uItemsAlloc = 64;
  457. pD->hIndex = (pstDSII)malloc(sizeof(stDSII) * 64);
  458. }
  459. else
  460. {
  461. int newSize = pD->uItemsAlloc * 2;
  462. stDSII * pTemphIndex = NULL;
  463. pTemphIndex = (pstDSII)
  464. realloc(pD->hIndex, (size_t)newSize * sizeof(stDSII));
  465. if (pTemphIndex == NULL)
  466. {
  467. uRv = SF_ERR_MEMORY_ERROR;
  468. goto OSFexit;
  469. }
  470. else
  471. {
  472. pD->uItemsAlloc = newSize;
  473. pD->hIndex = pTemphIndex;
  474. }
  475. }
  476. }
  477. if (pD->hData == 0)
  478. {
  479. pD->hData = (BYTE *)malloc(ROUND_UP(4096));
  480. pD->dwDataSize = ROUND_UP(4096);
  481. pD->dwDataUsed = 0;
  482. }
  483. /*
  484. * Add the item at the end of the list
  485. */
  486. nRv = pD->uItemCount;
  487. pIx = pI;
  488. pIx += nRv;
  489. pIx->uIndex = sID;
  490. pIx->dwSize = dwSZ;
  491. pIx->dwOffset = (DWORD)(pszPtr - pszStr);
  492. pD->uItemCount += 1;
  493. //fread(pszPtr, sSZ, 1, f);
  494. if( (DWORD)dwSZ > uSize )
  495. {
  496. CloseHandle(hFile);
  497. uRv = SF_ERR_FILE_FORMAT;
  498. goto OSFexit;
  499. }
  500. if (ReadFile(hFile, pszPtr, (DWORD)dwSZ, &dw, 0) == FALSE)
  501. {
  502. CloseHandle(hFile);
  503. uRv = SF_ERR_FILE_ACCESS;
  504. goto OSFexit;
  505. }
  506. pszPtr += dwSZ;
  507. asSessionFiles[uNdx].dwDataUsed += dwSZ;
  508. }
  509. else
  510. {
  511. TCHAR acBuffer[FNAME_LEN];
  512. //fread(acBuffer, dwSZ, 1, f);
  513. if( (DWORD)dwSZ > sizeof(acBuffer) )
  514. {
  515. CloseHandle(hFile);
  516. uRv = SF_ERR_FILE_FORMAT;
  517. goto OSFexit;
  518. }
  519. if (ReadFile(hFile, acBuffer, (DWORD)dwSZ, &dw, 0) == FALSE)
  520. {
  521. CloseHandle(hFile);
  522. uRv = SF_ERR_FILE_ACCESS;
  523. goto OSFexit;
  524. }
  525. sfPutSessionItem(uNdx + 1, (unsigned int)sID,
  526. (unsigned long)dwSZ, acBuffer);
  527. }
  528. }
  529. /*
  530. * Free things up
  531. */
  532. CloseHandle(hFile);
  533. }
  534. return SF_OK;
  535. }
  536. OSFexit:
  537. if (uNdx != SESS_FILE_MAX)
  538. {
  539. /*
  540. * General cleanup
  541. */
  542. if (asSessionFiles[uNdx].hFilename)
  543. {
  544. free(asSessionFiles[uNdx].hFilename);
  545. asSessionFiles[uNdx].hFilename = NULL;
  546. }
  547. if (asSessionFiles[uNdx].hData)
  548. {
  549. free(asSessionFiles[uNdx].hData);
  550. asSessionFiles[uNdx].hData = NULL;
  551. }
  552. if (asSessionFiles[uNdx].hIndex)
  553. {
  554. free(asSessionFiles[uNdx].hIndex);
  555. asSessionFiles[uNdx].hIndex = NULL;
  556. }
  557. memset(&asSessionFiles[uNdx], 0, sizeof(stDSFP));
  558. }
  559. return uRv;
  560. }
  561. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  562. * FUNCTION: sfFlushSessionFile
  563. *
  564. * DESCRIPTION:
  565. * This function is called to write all of the data in a session file out to
  566. * disk and release any and all memory associated with the session file handle.
  567. * It will not do anything if the session file does not have a file name
  568. * associated with it.
  569. *
  570. * ARGUEMENTS:
  571. * SF_HANDLE sF -- the session file handle
  572. *
  573. * RETURNS:
  574. * ZERO if the file is written, an error code < 0 if there is and error.
  575. */
  576. int sfFlushSessionFile(const SF_HANDLE sF)
  577. {
  578. int nRv = 0;
  579. int uNdx = sF - 1;
  580. int x;
  581. USHORT usIndex;
  582. TCHAR *pszName;
  583. TCHAR *pszPtr;
  584. pstDSII pI;
  585. HANDLE hFile;
  586. DWORD dw;
  587. if (uNdx >= SESS_FILE_MAX)
  588. {
  589. nRv = SF_ERR_BAD_PARAMETER;
  590. goto CSFexit;
  591. }
  592. if (asSessionFiles[uNdx].uBusy == 0)
  593. {
  594. nRv = SF_ERR_BAD_PARAMETER;
  595. goto CSFexit;
  596. }
  597. if (asSessionFiles[uNdx].fOpen == 0)
  598. {
  599. nRv = SF_ERR_FILE_ACCESS;
  600. goto CSFexit;
  601. }
  602. if (asSessionFiles[uNdx].uChanged != 0)
  603. {
  604. if (asSessionFiles[uNdx].hFilename == NULL)
  605. {
  606. nRv = SF_ERR_FILE_ACCESS;
  607. goto CSFexit;
  608. }
  609. pszName = asSessionFiles[uNdx].hFilename;
  610. /* TODO: put in code to create directorys as necessary */
  611. //f = fopen(pszName, "wb");
  612. hFile = CreateFile(pszName, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
  613. if (hFile == INVALID_HANDLE_VALUE)
  614. {
  615. nRv = SF_ERR_FILE_ACCESS;
  616. goto CSFexit;
  617. }
  618. pszPtr = (TCHAR *)asSessionFiles[uNdx].hData;
  619. /*
  620. * Write out the header first
  621. */
  622. if (StrCharGetStrLength(pszPtr) == 0)
  623. {
  624. /*
  625. * Write out an empty header
  626. */
  627. WriteFile(hFile, pszHdr, HDR_SIZE * sizeof(TCHAR), &dw, 0);
  628. }
  629. else
  630. {
  631. /*
  632. * Write out the current header
  633. */
  634. WriteFile(hFile, pszPtr, HDR_SIZE * sizeof(TCHAR), &dw, 0);
  635. }
  636. pszPtr += HDR_SIZE;
  637. pI = asSessionFiles[uNdx].hIndex;
  638. /*
  639. * We loop thru the index and write out all of the stuff
  640. */
  641. for (x = 0; x < asSessionFiles[uNdx].uItemCount; x += 1)
  642. {
  643. if (pI->dwSize != 0)
  644. {
  645. #if defined(DEBUG_OUTPUT)
  646. unsigned char acBuffer[64];
  647. wsprintf(acBuffer,
  648. "w %d(0x%x) %d\r\n",
  649. pI->uIndex, pI->uIndex, pI->dwSize);
  650. OutputDebugString(acBuffer);
  651. #endif
  652. usIndex = (USHORT)pI->uIndex;
  653. WriteFile(hFile, &usIndex, sizeof(USHORT), &dw, 0);
  654. WriteFile(hFile, &pI->dwSize, sizeof(DWORD), &dw, 0);
  655. WriteFile(hFile, pszPtr, (size_t)pI->dwSize * sizeof(TCHAR),
  656. &dw, 0);
  657. pszPtr += pI->dwSize;
  658. }
  659. pI += 1;
  660. }
  661. CloseHandle(hFile);
  662. asSessionFiles[uNdx].uChanged = 0;
  663. // Finally, notify the shell so it can update the icon.
  664. //
  665. SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATH,
  666. asSessionFiles[uNdx].hFilename, 0);
  667. }
  668. CSFexit:
  669. return nRv;
  670. }
  671. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  672. * FUNCTION: sfReleaseSessionFile
  673. *
  674. * DESCRIPTION:
  675. * This function is called to release any and all memory associated with the
  676. * session file handle. This function by itself DOES NOT write any data out
  677. * to the file. That must be done elsewhere.
  678. *
  679. * ARGUEMENTS:
  680. * SF_HANDLE sF -- the session file handle
  681. *
  682. * RETURNS:
  683. * ZERO if everything is OK, otherwise an error code < 0.
  684. */
  685. int sfReleaseSessionFile(const SF_HANDLE sF)
  686. {
  687. unsigned int uNdx = (unsigned int)sF - 1;
  688. if (uNdx > SESS_FILE_MAX)
  689. return SF_ERR_BAD_PARAMETER;
  690. if (asSessionFiles[uNdx].uBusy == 0)
  691. return SF_ERR_BAD_PARAMETER;
  692. asSessionFiles[uNdx].uBusy = 0;
  693. if (asSessionFiles[uNdx].hFilename)
  694. {
  695. free(asSessionFiles[uNdx].hFilename);
  696. asSessionFiles[uNdx].hFilename = NULL;
  697. }
  698. if (asSessionFiles[uNdx].hData)
  699. {
  700. free(asSessionFiles[uNdx].hData);
  701. asSessionFiles[uNdx].hData = NULL;
  702. }
  703. if (asSessionFiles[uNdx].hIndex)
  704. {
  705. free(asSessionFiles[uNdx].hIndex);
  706. asSessionFiles[uNdx].hIndex = NULL;
  707. }
  708. memset(&asSessionFiles[uNdx], 0, sizeof(stDSFP));
  709. return 0;
  710. }
  711. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  712. * FUNCTION: sfCloseSessionFile
  713. *
  714. * DESCRIPTION:
  715. * This function is called to release any and all memory associated with the
  716. * session file handle. This function by itself DOES NOT write any data out
  717. * to the file. That must be done elsewhere.
  718. *
  719. * ARGUEMENTS:
  720. * SF_HANDLE sF -- the session file handle
  721. *
  722. * RETURNS:
  723. * ZERO if everything is OK, otherwise an error code < 0.
  724. */
  725. int sfCloseSessionFile(const SF_HANDLE sF)
  726. {
  727. int rV1, rV2;
  728. rV1 = sfFlushSessionFile(sF);
  729. rV2 = sfReleaseSessionFile(sF);
  730. if (rV1 != 0)
  731. return rV1;
  732. return rV2;
  733. }
  734. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  735. * FUNCTION: sfGetSessionFileName
  736. *
  737. * DESCRIPTION:
  738. * This function is called to return the file name currently associated with
  739. * the session file handle.
  740. *
  741. * ARGUEMENTS:
  742. * SF_HANDLE sF -- the session file handle
  743. * INT nSize -- the size of the following buffer
  744. * PCHAR pszName -- the address of the buffer to copy the name to
  745. *
  746. * RETURNS:
  747. * ZERO if everything is OK, otherwise an error code < 0;
  748. */
  749. int sfGetSessionFileName(const SF_HANDLE sF, const int nSize, TCHAR *pszName)
  750. {
  751. int uNdx = sF - 1;
  752. #if DEADWOOD
  753. TCHAR *pszStr = NULL;
  754. int len;
  755. #endif
  756. if (uNdx > SESS_FILE_MAX)
  757. return SF_ERR_BAD_PARAMETER;
  758. if (asSessionFiles[uNdx].uBusy == 0)
  759. return SF_ERR_BAD_PARAMETER;
  760. if (asSessionFiles[uNdx].hFilename == NULL)
  761. return SF_ERR_BAD_PARAMETER;
  762. //
  763. // Use StrCharCopyN() to copy the filename into the buffer passed.
  764. // This will localize our revisions to the string manipulation
  765. // functions if needed at a later date. REV: 03/01/2001
  766. //
  767. #if DEADWOOD
  768. pszStr = asSessionFiles[uNdx].hFilename;
  769. //strncpy(pszName, pszStr, nSize);
  770. // JYF 03-Dec-1998 we don't want to read more than strlen
  771. // of pszStr and nSize so not to read from inaccessible
  772. // memory when running with debug heap.
  773. len = min (nSize, lstrlen (pszStr)+1);
  774. MemCopy(pszName, pszStr, (size_t)len * sizeof(TCHAR));
  775. pszName[nSize-1] = TEXT('\0');
  776. #else
  777. StrCharCopyN(pszName, asSessionFiles[uNdx].hFilename, nSize);
  778. #endif
  779. return SF_OK;
  780. }
  781. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  782. * FUNCTION: sfSetSessionFileName
  783. *
  784. * DESCRIPTION:
  785. * This function is called to change the name currently associated with the
  786. * session file handle. It does not cause the session file handle to reload
  787. * any data or access the disk at all. Data files are read when the session
  788. * file is opened and written when the session file is closed.
  789. *
  790. * ARGUEMENTS:
  791. * SF_HANDLE sF -- the session file handle
  792. * PCHAR pszName -- the address of the new file name
  793. *
  794. * RETURNS:
  795. * ZERO if everything is OK, otherwise and error code < 0;
  796. */
  797. int sfSetSessionFileName(const SF_HANDLE sF, const TCHAR *pszName)
  798. {
  799. unsigned int uNdx = (unsigned int)sF - 1;
  800. TCHAR *pszStr = NULL;
  801. if (uNdx > SESS_FILE_MAX)
  802. return SF_ERR_BAD_PARAMETER;
  803. if (asSessionFiles[uNdx].uBusy == 0)
  804. return SF_ERR_BAD_PARAMETER;
  805. if (asSessionFiles[uNdx].fOpen == 0)
  806. return SF_ERR_FILE_ACCESS;
  807. if (asSessionFiles[uNdx].hFilename == NULL)
  808. {
  809. asSessionFiles[uNdx].hFilename = (TCHAR *)malloc(FNAME_LEN * sizeof(TCHAR));
  810. if (asSessionFiles[uNdx].hFilename == NULL)
  811. return SF_ERR_MEMORY_ERROR;
  812. }
  813. pszStr = asSessionFiles[uNdx].hFilename;
  814. TCHAR_Fill(pszStr, TEXT('\0'), FNAME_LEN);
  815. StrCharCopyN(pszStr, (LPTSTR)pszName, FNAME_LEN);
  816. pszStr = NULL;
  817. asSessionFiles[uNdx].uChanged = 1;
  818. return 0;
  819. }
  820. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  821. * FUNCTION: sfGetSessionItem
  822. *
  823. * DESCRIPTION:
  824. * This function is called to get data from the session file handle. It can
  825. * also be used to get the size of a data item.
  826. *
  827. * If the last arguement, pvData, is NULL, then the size of the item is
  828. * returned in *pulSize. If pvData is not NULL, up to *pulSize bytes are
  829. * returned at pvData. If the number of bytes returned is less than *pulData,
  830. * the new size is set in *pulSize.
  831. *
  832. * ARGUEMENTS:
  833. * SF_HANDLE sF -- the session file handle
  834. * uId -- ID if the item
  835. * pulSize -- where the size is found or returned
  836. * pvData -- where the data is to be placed
  837. *
  838. * RETURNS:
  839. * ZERO if everything is OK, otherwise and error code < 0;
  840. */
  841. int sfGetSessionItem(const SF_HANDLE sF,
  842. const unsigned int uId,
  843. unsigned long *pulSize,
  844. void *pvData)
  845. {
  846. int lReturn = SF_ERR_BAD_PARAMETER;
  847. int uNdx = sF - 1;
  848. int dwMinSize;
  849. int low;
  850. int mid;
  851. int high;
  852. pstDSII pI;
  853. pstDSII pIx;
  854. BYTE * pszData;
  855. if (uNdx > SESS_FILE_MAX)
  856. {
  857. lReturn = SF_ERR_BAD_PARAMETER;
  858. }
  859. else if (uNdx < 0)
  860. {
  861. lReturn = SF_ERR_BAD_PARAMETER;
  862. }
  863. else if (asSessionFiles[uNdx].uBusy == 0)
  864. {
  865. lReturn = SF_ERR_BAD_PARAMETER;
  866. }
  867. else if (asSessionFiles[uNdx].fOpen == 0)
  868. {
  869. lReturn = SF_ERR_FILE_ACCESS;
  870. }
  871. else if (asSessionFiles[uNdx].uItemCount == 0)
  872. {
  873. lReturn = SF_ERR_BAD_PARAMETER;
  874. }
  875. else if ((uId < 1) || (uId > 0x7FFF))
  876. {
  877. lReturn = SF_ERR_BAD_PARAMETER;
  878. }
  879. /*
  880. * See if the item is in the index
  881. */
  882. else if (asSessionFiles[uNdx].hIndex == (pstDSII)0)
  883. {
  884. lReturn = SF_ERR_BAD_PARAMETER;
  885. }
  886. else
  887. {
  888. pI = asSessionFiles[uNdx].hIndex;
  889. low = 0;
  890. high = asSessionFiles[uNdx].uItemCount - 1;
  891. while (low <= high)
  892. {
  893. mid = (low + high) / 2;
  894. pIx = pI + mid;
  895. if ((int)uId < pIx->uIndex)
  896. {
  897. high = mid - 1;
  898. }
  899. else if ((int)uId > pIx->uIndex)
  900. {
  901. low = mid + 1;
  902. }
  903. else
  904. {
  905. /*
  906. * Found the item, see what they want to know
  907. */
  908. if (pvData == NULL)
  909. {
  910. *pulSize = (unsigned long)pIx->dwSize;
  911. }
  912. else
  913. {
  914. pszData = asSessionFiles[uNdx].hData;
  915. dwMinSize = (int)*pulSize;
  916. if (dwMinSize > pIx->dwSize)
  917. {
  918. dwMinSize = pIx->dwSize;
  919. }
  920. if (dwMinSize)
  921. {
  922. MemCopy(pvData, pszData + pIx->dwOffset, (size_t)dwMinSize);
  923. }
  924. }
  925. lReturn = SF_OK;
  926. break;
  927. }
  928. }
  929. }
  930. return lReturn;
  931. }
  932. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  933. * FUNCTION: sfCompareSessionItem
  934. *
  935. * DESCRIPTION:
  936. * This function is called to check and see if an item exists in the data
  937. * and if it is the same as the passed in item.
  938. *
  939. * ARGUEMENTS:
  940. * SF_HANDLE sF -- the session file handle
  941. * uId -- the ID of the item
  942. * ulSize -- the size of the item
  943. * pvData -- address of the data
  944. *
  945. * RETURNS:
  946. * TRUE if the two items are the same, otherwise false.
  947. */
  948. int sfCompareSessionItem(const SF_HANDLE sF,
  949. const unsigned int uId,
  950. const unsigned long ulSize,
  951. const void *pvData)
  952. {
  953. int uNdx = sF - 1;
  954. int low, mid, high;
  955. pstDSII pI;
  956. pstDSII pIx;
  957. BYTE *pszData;
  958. /*
  959. * See if the item is in the index
  960. */
  961. if (asSessionFiles[uNdx].hIndex == (pstDSII)0)
  962. return FALSE;
  963. pI = asSessionFiles[uNdx].hIndex;
  964. low = 0;
  965. high = asSessionFiles[uNdx].uItemCount - 1;
  966. while (low <= high)
  967. {
  968. mid = (low + high) / 2;
  969. pIx = pI + mid;
  970. if ((int)uId < pIx->uIndex)
  971. high = mid - 1;
  972. else if ((int)uId > pIx->uIndex)
  973. low = mid + 1;
  974. else
  975. {
  976. /*
  977. * Check and see if the sizes are the same
  978. */
  979. if (ulSize != (unsigned long)pIx->dwSize)
  980. return FALSE;
  981. /*
  982. * Check and see if the data is the same
  983. */
  984. pszData = asSessionFiles[uNdx].hData + pIx->dwOffset;
  985. if (memcmp((BYTE *)pvData, pszData, ulSize) == 0)
  986. return TRUE;
  987. return FALSE;
  988. }
  989. }
  990. return FALSE;
  991. }
  992. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  993. * FUNCTION: sfPutSessionItem
  994. *
  995. * DESCRIPTION:
  996. * This function is called to add or modify an entry in the session file data
  997. * associated with the current session file handle. It does not cause the
  998. * actual session file itself to be written. That is done only when the
  999. * session file handle is closed.
  1000. *
  1001. * ARGUEMENTS:
  1002. * SF_HANDLE sF -- the session file handle
  1003. * uId -- the ID of the item
  1004. * ulSize -- the size of the item
  1005. * pvData -- address of the data
  1006. *
  1007. * RETURNS:
  1008. * ZERO if everything is OK, otherwise and error code < 0;
  1009. */
  1010. int sfPutSessionItem(const SF_HANDLE sF,
  1011. const unsigned int uId,
  1012. const unsigned long ulSize,
  1013. const void *pvData)
  1014. {
  1015. int uNdx = sF - 1;
  1016. int x, y;
  1017. int32 dwSlide;
  1018. int32 dwOffset;
  1019. int32 dwNewSize;
  1020. pstDSII pI;
  1021. pstDSII pIx, pIy;
  1022. BYTE *pszData;
  1023. #if defined(DEBUG_OUTPUT)
  1024. unsigned char acBuffer[80];
  1025. #endif
  1026. if (uNdx > SESS_FILE_MAX)
  1027. return SF_ERR_BAD_PARAMETER;
  1028. if (asSessionFiles[uNdx].uBusy == 0)
  1029. return SF_ERR_BAD_PARAMETER;
  1030. if (asSessionFiles[uNdx].fOpen == 0)
  1031. return SF_ERR_FILE_ACCESS;
  1032. if ((uId < 1) || (uId > 0x7FFF))
  1033. return SF_ERR_BAD_PARAMETER;
  1034. if (sfCompareSessionItem(sF, uId, ulSize, pvData))
  1035. return SF_OK;
  1036. x = sfAddToIndex(uNdx, (unsigned short)uId, 0, 0);
  1037. pI = asSessionFiles[uNdx].hIndex;
  1038. if (x != (-1))
  1039. {
  1040. pIx = pI + x;
  1041. if (pIx->dwSize == 0)
  1042. {
  1043. /*
  1044. * Its a new item
  1045. */
  1046. dwSlide = (int32)ulSize;
  1047. if (x == 0)
  1048. dwOffset = HDR_SIZE;
  1049. else
  1050. dwOffset = (pI+x-1)->dwOffset + (pI+x-1)->dwSize;
  1051. #if defined(DEBUG_OUTPUT)
  1052. wsprintf(acBuffer,
  1053. "New 0x%x slide %d offset 0x%x",
  1054. uId, dwSlide, dwOffset);
  1055. OutputDebugString(acBuffer);
  1056. #endif
  1057. }
  1058. else
  1059. {
  1060. /*
  1061. * Its a replacement item
  1062. */
  1063. dwSlide = (int)ulSize - (int)pIx->dwSize;
  1064. dwOffset = pIx->dwOffset;
  1065. #if defined(DEBUG_OUTPUT)
  1066. wsprintf(acBuffer,
  1067. "Rep 0x%x slide %d offset 0x%x",
  1068. uId, dwSlide, dwOffset);
  1069. OutputDebugString(acBuffer);
  1070. #endif
  1071. }
  1072. /*
  1073. * Check the memory requirements
  1074. */
  1075. dwNewSize = asSessionFiles[uNdx].dwDataUsed + dwSlide;
  1076. if (dwNewSize > asSessionFiles[uNdx].dwDataSize)
  1077. {
  1078. /*
  1079. * Need to allocate a new chunk of memory
  1080. */
  1081. BYTE *hG =(BYTE *)
  1082. realloc(asSessionFiles[uNdx].hData, ROUND_UP(dwNewSize));
  1083. if (hG == NULL)
  1084. {
  1085. return SF_ERR_MEMORY_ERROR;
  1086. }
  1087. else
  1088. {
  1089. asSessionFiles[uNdx].hData = hG;
  1090. asSessionFiles[uNdx].dwDataSize = ROUND_UP(dwNewSize);
  1091. }
  1092. }
  1093. /*
  1094. * Move the old data to the point necessary
  1095. */
  1096. pszData = asSessionFiles[uNdx].hData;
  1097. asSessionFiles[uNdx].dwDataUsed = dwNewSize;
  1098. if (dwSlide < 0)
  1099. {
  1100. /* shrink the current space */
  1101. dwNewSize = asSessionFiles[uNdx].dwDataSize;
  1102. dwNewSize -= dwOffset;
  1103. dwNewSize += dwSlide;
  1104. memmove(pszData + dwOffset, /* destination */
  1105. pszData + dwOffset - dwSlide, /* source */
  1106. (size_t)(dwNewSize - 1)); /* count */
  1107. #if defined(DEBUG_OUTPUT)
  1108. wsprintf(acBuffer,
  1109. " shrink from 0x%lx to 0x%lx size 0x%x\r\n",
  1110. (long)(pszData + dwOffset - dwSlide),
  1111. (long)(pszData + dwOffset),
  1112. dwNewSize -1);
  1113. OutputDebugString(acBuffer);
  1114. #endif
  1115. }
  1116. else
  1117. {
  1118. /* expand the current space */
  1119. dwNewSize = asSessionFiles[uNdx].dwDataSize;
  1120. dwNewSize -= dwOffset;
  1121. dwNewSize -= dwSlide;
  1122. memmove(pszData + dwOffset + dwSlide, /* destination */
  1123. pszData + dwOffset, /* source */
  1124. (size_t)(dwNewSize - 1)); /* count */
  1125. #if defined(DEBUG_OUTPUT)
  1126. wsprintf(acBuffer,
  1127. " expand from 0x%lx to 0x%lx size 0x%x\r\n",
  1128. (long)(pszData + dwOffset),
  1129. (long)(pszData + dwOffset + dwSlide),
  1130. dwNewSize - 1);
  1131. OutputDebugString(acBuffer);
  1132. #endif
  1133. }
  1134. /*
  1135. * Copy in the new data
  1136. */
  1137. memmove(pszData + dwOffset, /* destination */
  1138. pvData, /* source */
  1139. (unsigned int)ulSize); /* count */
  1140. /*
  1141. * Update the item in the index for the current item
  1142. */
  1143. pIx->dwSize = (int32)ulSize;
  1144. pIx->dwOffset = dwOffset;
  1145. /*
  1146. * Adjust all the following items in the index
  1147. */
  1148. for (y = x + 1; y < (int)asSessionFiles[uNdx].uItemCount; y += 1)
  1149. {
  1150. pIy = pI + y;
  1151. pIy->dwOffset += dwSlide;
  1152. }
  1153. asSessionFiles[uNdx].uChanged = 1;
  1154. return 0;
  1155. }
  1156. return SF_ERR_BAD_PARAMETER;
  1157. }