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.

2557 lines
98 KiB

  1. //____________________________________________________________________________
  2. //
  3. // (C) Copyright Seagate Software, Inc. 1994-1996
  4. // � 1998 Seagate Software, Inc. All rights reserved.
  5. //
  6. // All Rights Reserved Worldwide.
  7. //
  8. //____________________________________________________________________________
  9. //
  10. // FILE NAME : mtf_api.c
  11. //
  12. // DESCRIPTION : mtf api implementation
  13. //
  14. // CREATED: 6/20/95
  15. //
  16. //____________________________________________________________________________
  17. //
  18. // $Revision: 1.35 $
  19. // $Date: 02 Feb 1995 15:47:04 $
  20. // $Modtime: 02 Feb 1995 15:37:38 $
  21. //
  22. //____________________________________________________________________________
  23. // *****************************************************************************/
  24. #include <assert.h>
  25. #include <time.h>
  26. #include <string.h>
  27. #include <wchar.h>
  28. #include <stralign.h>
  29. #include "stdafx.h"
  30. #include "mtfapi.h"
  31. static USHORT iCountMTFa = 0; // Count of existing objects
  32. //
  33. // Constructor
  34. //
  35. CMTFApi::CMTFApi(void)
  36. {
  37. m_uAlignmentFactor = 0;
  38. m_iNumStrings = 0;
  39. for (int i = 0; i < iNUMSTRINGS; ++i){
  40. m_aszStrings[i] = 0;
  41. }
  42. iCountMTFa++;
  43. }
  44. //
  45. // Destructor
  46. //
  47. CMTFApi::~CMTFApi()
  48. {
  49. ClearStrings();
  50. iCountMTFa--;
  51. }
  52. /* ==================================================================================
  53. String Management
  54. When reading blocks, the strings are not null terminated -- we would like to
  55. pull them out and deliver them back in the ####_INFO structures in a civilized
  56. (null terminated) way. Thus, just set up an array of malloc'ec strings.
  57. Each call that uses strings should first call "ClearStrings" -- strings returned
  58. to the user will only be good up until the next call...
  59. ================================================================================= */
  60. // - returns the size of a wchar_t string
  61. // and returns zero for a null pointer
  62. size_t CMTFApi::wstrsize(wchar_t *s)
  63. {
  64. if (s)
  65. return wcslen(s) * sizeof(wchar_t);
  66. else
  67. return 0;
  68. }
  69. // - returns the size of a wchar_t unaligned string
  70. // and returns zero for a null pointer
  71. size_t CMTFApi::ua_wstrsize(wchar_t UNALIGNED *s)
  72. {
  73. if (s)
  74. return ua_wcslen(s) * sizeof(wchar_t);
  75. else
  76. return 0;
  77. }
  78. // - frees all allocated pointers in m_aszStrings and sets
  79. // m_iNumStrings to zero
  80. void CMTFApi::ClearStrings()
  81. {
  82. int i;
  83. for (i = 0; i < iNUMSTRINGS; ++i)
  84. {
  85. if (m_aszStrings[i])
  86. free(m_aszStrings[i]);
  87. m_aszStrings[i] = 0;
  88. }
  89. m_iNumStrings = 0;
  90. }
  91. // - allocates a string in m_aszStrings that is a copy of pString
  92. // (pString need not be null terminated)
  93. // (note -- iSize is the size of the string in bytes -- not the length!!!!!
  94. wchar_t * CMTFApi::MakeString(wchar_t UNALIGNED * pString, size_t iSize)
  95. {
  96. size_t i;
  97. if (m_iNumStrings >= iNUMSTRINGS) {
  98. return NULL;
  99. }
  100. m_aszStrings[m_iNumStrings] = (wchar_t *)malloc(iSize + sizeof(wchar_t));
  101. if (!m_aszStrings[m_iNumStrings])
  102. return NULL;
  103. for (i = 0; i < iSize / sizeof(wchar_t); ++i)
  104. m_aszStrings[m_iNumStrings][i] = pString[i];
  105. m_aszStrings[m_iNumStrings][i] = L'\0';
  106. return m_aszStrings[m_iNumStrings++];
  107. }
  108. /* ==================================================================================
  109. Other data structures
  110. ================================================================================= */
  111. #pragma pack(1)
  112. /***********************************************************************************
  113. ************************************************************************************
  114. ************************************************************************************
  115. **** MTF On Tape Structures
  116. ************************************************************************************
  117. ************************************************************************************
  118. ***********************************************************************************/
  119. /* ==================================================================================
  120. Common DBLK Header
  121. - The common dblk header exactly as it appears on tape in the head of the dblks
  122. ================================================================================== */
  123. typedef struct {
  124. UINT8 acBlockType[4]; /* 00h Unique identifier, see above */
  125. UINT32 uBlockAttributes; /* 04h Common attributes for this block */
  126. UINT16 uOffsetToFirstStream; /* 08h Offset to data associated with this */
  127. /* DBLK, or offset to next DBLK or */
  128. /* filemark if there is no associated */
  129. /* data. */
  130. UINT8 uOSID; /* 0Ah Machine/OS id where written, low byte */
  131. UINT8 uOSVersion; /* 0Bh Machine/OS id where written, high byte */
  132. UINT64 uDisplayableSize; /* 0Ch Displayable data size */
  133. UINT64 uFormatLogicalAddress; /* 14h Logical blk address relative to SSET */
  134. UINT16 uReservedForMBC; /* 1Ch Reserved for Media Based Catalog */
  135. UINT16 uSoftwareCompression; /* 1Eh Software Compression Algorithm ***/
  136. UINT8 acReserved1[4]; /* 20h reserved */
  137. UINT32 uControlBlockId; /* 24h Used for error recovery */
  138. UINT8 acReserved2[4]; /* 28h reserved */
  139. MTF_TAPE_ADDRESS sOSSpecificData; /* 2Ch Size and offset of OS specific stuff */
  140. UINT8 uStringType; /* 30h ASCII, Unicode, etc. */
  141. UINT8 uReserved3; /* 31h for alignment purposes */
  142. UINT16 uHeaderCheckSum; /* 32h Checksum of the block header. The */
  143. /* algorithm is: XOR each word preceeding */
  144. /* this one and store the result here. */
  145. /* (When the checksum is verified the */
  146. /* 'block_type' is also checked for a */
  147. /* non-zero value. */
  148. } MTF_DBLK_HDR;
  149. /* ==================================================================================
  150. DBLK TAPE Header
  151. - The TAPE DBLK, exactly as it appears on tape, including the common DBLK header (MTF_DBLK_HDR)
  152. ================================================================================== */
  153. typedef struct { /* MTF_DBLK_TAPE */
  154. MTF_DBLK_HDR sBlockHeader;
  155. UINT32 uTapeFamilyId;
  156. UINT32 uTapeAttributes;
  157. UINT16 uTapeSequenceNumber;
  158. UINT16 uPasswordEncryptionAlgorithm;
  159. UINT16 uSoftFilemarkBlockSize; /* Or ECC Algorithm */
  160. UINT16 uTapeCatalogType;
  161. MTF_TAPE_ADDRESS sTapeName;
  162. MTF_TAPE_ADDRESS sTapeDescription;
  163. MTF_TAPE_ADDRESS sTapePassword;
  164. MTF_TAPE_ADDRESS sSoftware_name;
  165. UINT16 uAlignmentFactor;
  166. UINT16 uSoftwareVendorId;
  167. MTF_DATE_TIME sTapeDate;
  168. UINT8 uMTFMajorVersion;
  169. } MTF_DBLK_TAPE;
  170. /* ==================================================================================
  171. Start of Set DBLK (SSET)
  172. - The SSET DBLK, exactly as it appears on tape, including the common DBLK header (MTF_DBLK_HDR)
  173. ================================================================================== */
  174. typedef struct {
  175. MTF_DBLK_HDR sBlockHeader;
  176. UINT32 uSSETAttributes;
  177. UINT16 uPasswordEncryptionAlgorithm;
  178. UINT16 uDataEncryptionAlgorithm; /* Or Software Compression Algorithm ***/
  179. UINT16 uSoftwareVendorId;
  180. UINT16 uDataSetNumber;
  181. MTF_TAPE_ADDRESS sDataSetName;
  182. MTF_TAPE_ADDRESS sDataSetDescription;
  183. MTF_TAPE_ADDRESS sDataSetPassword;
  184. MTF_TAPE_ADDRESS sUserName;
  185. UINT64 uPhysicalBlockAddress;
  186. MTF_DATE_TIME sMediaWriteDate;
  187. UINT8 uSoftwareVerMjr;
  188. UINT8 uSoftwareVerMnr;
  189. UINT8 uTimeZone;
  190. UINT8 uMTFMinorVer;
  191. UINT8 uTapeCatalogVersion;
  192. } MTF_DBLK_SSET;
  193. /* ==================================================================================
  194. Volume DBLK (VOLB)
  195. - The VOLB DBLK, exactly as it appears on tape, including the common DBLK header (MTF_DBLK_HDR)
  196. ================================================================================== */
  197. typedef struct {
  198. MTF_DBLK_HDR sBlockHeader;
  199. UINT32 uVolumeAttributes;
  200. MTF_TAPE_ADDRESS sDeviceName;
  201. MTF_TAPE_ADDRESS sVolumeName;
  202. MTF_TAPE_ADDRESS sMachineName;
  203. MTF_DATE_TIME sMediaWriteDate;
  204. } MTF_DBLK_VOLB;
  205. /* ==================================================================================
  206. Directory DBLK (DIRB)
  207. - The DIRB DBLK, exactly as it appears on tape, including the common DBLK header (MTF_DBLK_HDR)
  208. ================================================================================== */
  209. typedef struct {
  210. MTF_DBLK_HDR sBlockHeader;
  211. UINT32 uDirectoryAttributes;
  212. MTF_DATE_TIME sLastModificationDate;
  213. MTF_DATE_TIME sCreationDate;
  214. MTF_DATE_TIME sBackupDate;
  215. MTF_DATE_TIME sLastAccessDate;
  216. UINT32 uDirectoryId;
  217. MTF_TAPE_ADDRESS sDirectoryName;
  218. } MTF_DBLK_DIRB;
  219. /* ==================================================================================
  220. Directory DBLK (FILE)
  221. - The FILE DBLK, exactly as it appears on tape, including the common DBLK header (MTF_DBLK_HDR)
  222. ================================================================================== */
  223. typedef struct {
  224. MTF_DBLK_HDR sBlockHeader;
  225. UINT32 uFileAttributes;
  226. MTF_DATE_TIME sLastModificationDate;
  227. MTF_DATE_TIME sCreationDate;
  228. MTF_DATE_TIME sBackupDate;
  229. MTF_DATE_TIME sLastAccessDate;
  230. UINT32 uDirectoryId;
  231. UINT32 uFileId;
  232. MTF_TAPE_ADDRESS sFileName;
  233. } MTF_DBLK_FILE;
  234. #pragma pack()
  235. /* ==================================================================================
  236. Corrupt File DBLK (CFIL)
  237. - use MTF_DBLK_CFIL_INFO -- same structure
  238. ================================================================================== */
  239. typedef MTF_DBLK_CFIL_INFO MTF_DBLK_CFIL;
  240. /* ==================================================================================
  241. End of Set Pad Block (ESPB)
  242. ================================================================================== */
  243. // consists only of header
  244. /* ==================================================================================
  245. End of Set Block (ESET)
  246. - use MTF_DBLK_ESET_INFO -- same structure
  247. ================================================================================== */
  248. typedef MTF_DBLK_ESET_INFO MTF_DBLK_ESET;
  249. /* ==================================================================================
  250. End of Set Block (EOTM)
  251. - use MTF_DBLK_EOTM_INFO -- same structure
  252. ================================================================================== */
  253. typedef MTF_DBLK_EOTM_INFO MTF_DBLK_EOTM;
  254. /* ==================================================================================
  255. Soft Filemark (SFMB)
  256. - use MTF_DBLK_SFMB_INFO -- same structure
  257. ================================================================================== */
  258. typedef MTF_DBLK_SFMB_INFO MTF_DBLK_SFMB;
  259. /* ==================================================================================
  260. StreamHeader
  261. - use MTF_STREAM_INFO -- same structure
  262. ================================================================================== */
  263. typedef MTF_STREAM_INFO MTF_STREAM;
  264. /***********************************************************************************
  265. ************************************************************************************
  266. ************************************************************************************
  267. **** MTF Misc Data Types
  268. ************************************************************************************
  269. ************************************************************************************
  270. ***********************************************************************************/
  271. /* ==================================================================================
  272. Alignment Factor
  273. ================================================================================== */
  274. /***********************************************************************************
  275. * MTF_SetAlignmentFactor()
  276. * ** MTF API FUNCTION **
  277. ***********************************************************************************/
  278. void CMTFApi::MTF_SetAlignmentFactor(UINT16 uAF)
  279. {
  280. // store the user's alignment factor in a private member
  281. m_uAlignmentFactor = uAF;
  282. }
  283. /***********************************************************************************
  284. * MTF_GetAlignmentFactor()
  285. * ** MTF API FUNCTION **
  286. ***********************************************************************************/
  287. UINT16 CMTFApi::MTF_GetAlignmentFactor()
  288. {
  289. return m_uAlignmentFactor;
  290. }
  291. /***********************************************************************************
  292. * MTF_PadToNextAlignmentFactor()
  293. * ** MTF API FUNCTION **
  294. ***********************************************************************************/
  295. DWORD CMTFApi::MTF_PadToNextAlignmentFactor(
  296. BYTE *pBuffer,
  297. size_t nBufUsed,
  298. size_t nBufferSize,
  299. size_t *pnSizeUsed)
  300. {
  301. size_t i;
  302. size_t nAlignment;
  303. MTF_STREAM_INFO sStream;
  304. // figure out what the next alignment value is and then pad out the user's buffer
  305. // with an SPAD, making sure the buffer is big enough
  306. nAlignment = Align(nBufUsed + sizeof(MTF_STREAM_INFO), MTF_GetAlignmentFactor());
  307. *pnSizeUsed = nAlignment;
  308. if (nBufferSize < nAlignment)
  309. return MTF_ERROR_BUFFER_TOO_SMALL;
  310. MTF_SetSTREAMDefaults(&sStream, "SPAD");
  311. sStream.uStreamLength = MTF_CreateUINT64(nAlignment - nBufUsed - sizeof(MTF_STREAM_INFO), 0);
  312. MTF_WriteStreamHeader(&sStream,
  313. pBuffer + nBufUsed,
  314. nBufferSize - nBufUsed,
  315. 0);
  316. for (i = nBufUsed + sizeof(MTF_STREAM_INFO); i < nAlignment; ++i)
  317. pBuffer[i] = 0;
  318. return MTF_ERROR_NONE;
  319. }
  320. /***********************************************************************************
  321. * MTF_PadToNextPhysicalBlockBoundary() - (bmd)
  322. * ** MTF API FUNCTION **
  323. ***********************************************************************************/
  324. DWORD CMTFApi::MTF_PadToNextPhysicalBlockBoundary(
  325. BYTE *pBuffer,
  326. size_t nBlockSize,
  327. size_t nBufUsed,
  328. size_t nBufferSize,
  329. size_t *pnSizeUsed)
  330. {
  331. size_t i;
  332. size_t nAlignment;
  333. MTF_STREAM_INFO sStream;
  334. // figure out what the next alignment value is and then pad out the user's buffer
  335. // with an SPAD, making sure the buffer is big enough
  336. nAlignment = Align(nBufUsed + sizeof(MTF_STREAM_INFO), nBlockSize);
  337. *pnSizeUsed = nAlignment;
  338. if (nBufferSize < nAlignment)
  339. return MTF_ERROR_BUFFER_TOO_SMALL;
  340. MTF_SetSTREAMDefaults(&sStream, "SPAD");
  341. sStream.uStreamLength = MTF_CreateUINT64(nAlignment - nBufUsed - sizeof(MTF_STREAM_INFO), 0);
  342. MTF_WriteStreamHeader(&sStream, pBuffer + nBufUsed, nBufferSize - nBufUsed, 0);
  343. for (i = nBufUsed + sizeof(MTF_STREAM_INFO); i < nAlignment; ++i)
  344. pBuffer[i] = 0;
  345. return MTF_ERROR_NONE;
  346. }
  347. /***********************************************************************************
  348. * MTF_CreateUINT64()
  349. * ** MTF API FUNCTION **
  350. ***********************************************************************************/
  351. UINT64 CMTFApi::MTF_CreateUINT64(UINT32 uLSB, UINT32 uMSB)
  352. {
  353. UINT64 uRet;
  354. uRet = (UINT64) uMSB << 32;
  355. uRet += uLSB;
  356. return uRet;
  357. }
  358. /* ==================================================================================
  359. Compressed date structure for storing dates in minimal space on tape:
  360. BYTE 0 BYTE 1 BYTE 2 BYTE 3 BYTE 4
  361. 76543210 76543210 76543210 76543210 76543210
  362. yyyyyyyy yyyyyymm mmdddddh hhhhmmmm mmssssss
  363. 33333333 33222222 22221111 11111100 00000000
  364. 98765432 10987654 32109876 54321098 76543210
  365. ================================================================================== */
  366. /***********************************************************************************
  367. * MTF_CreateDateTime()
  368. * ** MTF API FUNCTION **
  369. ***********************************************************************************/
  370. MTF_DATE_TIME CMTFApi::MTF_CreateDateTime(
  371. int iYear,
  372. int iMonth,
  373. int iDay,
  374. int iHour,
  375. int iMinute,
  376. int iSecond
  377. )
  378. {
  379. MTF_DATE_TIME sDateTime = {0};
  380. UINT16 temp ;
  381. // pack the date time structure with the arguments as per the diagram above
  382. temp = (UINT16)iYear << 2 ;
  383. sDateTime.dt_field[0] = ((UINT8 *)&temp)[1] ;
  384. sDateTime.dt_field[1] = ((UINT8 *)&temp)[0] ;
  385. temp = (UINT16)iMonth << 6 ;
  386. sDateTime.dt_field[1] |= ((UINT8 *)&temp)[1] ;
  387. sDateTime.dt_field[2] = ((UINT8 *)&temp)[0] ;
  388. temp = (UINT16)iDay << 1 ;
  389. sDateTime.dt_field[2] |= ((UINT8 *)&temp)[0] ;
  390. temp = (UINT16)iHour << 4 ;
  391. sDateTime.dt_field[2] |= ((UINT8 *)&temp)[1] ;
  392. sDateTime.dt_field[3] = ((UINT8 *)&temp)[0] ;
  393. temp = (UINT16)iMinute << 6 ;
  394. sDateTime.dt_field[3] |= ((UINT8 *)&temp)[1] ;
  395. sDateTime.dt_field[4] = ((UINT8 *)&temp)[0] ;
  396. temp = (UINT16)iSecond ;
  397. sDateTime.dt_field[4] |= ((UINT8 *)&temp)[0] ;
  398. return sDateTime;
  399. }
  400. /***********************************************************************************
  401. * MTF_CreateDateTimeFromTM()
  402. * ** MTF API FUNCTION **
  403. ***********************************************************************************/
  404. MTF_DATE_TIME CMTFApi::MTF_CreateDateTimeFromTM(
  405. struct tm *pT
  406. )
  407. {
  408. // translate call to MTF_CreateDateTime
  409. return MTF_CreateDateTime(pT->tm_year + 1900, pT->tm_mon + 1, pT->tm_mday, pT->tm_hour, pT->tm_min, pT->tm_sec);
  410. }
  411. /***********************************************************************************
  412. * MTF_CreateDateTimeToTM()
  413. * ** MTF API FUNCTION **
  414. ***********************************************************************************/
  415. void CMTFApi::MTF_CreateDateTimeToTM(
  416. MTF_DATE_TIME *pDT,
  417. struct tm *pT
  418. )
  419. {
  420. UINT8 temp[2] ;
  421. // unpack the MTF_DATE_TIME structure and store the results
  422. temp[0] = pDT->dt_field[1] ;
  423. temp[1] = pDT->dt_field[0] ;
  424. pT->tm_year = *((UINT16 *)temp) >> 2 ;
  425. temp[0] = pDT->dt_field[2] ;
  426. temp[1] = pDT->dt_field[1] ;
  427. pT->tm_mon = (*((UINT16 *)temp) >> 6) & 0x000F ;
  428. pT->tm_mday = (*((UINT16 *)temp) >> 1) & 0x001F ;
  429. temp[0] = pDT->dt_field[3] ;
  430. temp[1] = pDT->dt_field[2] ;
  431. pT->tm_hour = (*((UINT16 *)temp) >> 4) & 0x001F ;
  432. temp[0] = pDT->dt_field[4] ;
  433. temp[1] = pDT->dt_field[3] ;
  434. pT->tm_min = (*((UINT16 *)temp) >> 6) & 0x003F ;
  435. pT->tm_sec = *((UINT16 *)temp) & 0x003F ;
  436. }
  437. /***********************************************************************************
  438. * MTF_CreateDateNull()
  439. * ** MTF API FUNCTION **
  440. ***********************************************************************************/
  441. MTF_DATE_TIME CMTFApi::MTF_CreateDateNull()
  442. {
  443. MTF_DATE_TIME sDateTime = {0};
  444. return sDateTime;
  445. }
  446. /***********************************************************************************
  447. * MTF_CreateDateTimeFromFileTime()
  448. * ** MTF API FUNCTION **
  449. ***********************************************************************************/
  450. MTF_DATE_TIME CMTFApi::MTF_CreateDateTimeFromFileTime(
  451. FILETIME sFileTime
  452. )
  453. {
  454. SYSTEMTIME sSystemTime;
  455. FileTimeToSystemTime(&sFileTime, &sSystemTime);
  456. return MTF_CreateDateTime(sSystemTime.wYear,
  457. sSystemTime.wMonth,
  458. sSystemTime.wDay,
  459. sSystemTime.wHour,
  460. sSystemTime.wMinute,
  461. sSystemTime.wSecond);
  462. }
  463. /***********************************************************************************
  464. ************************************************************************************
  465. **** MTF internal HELPER FUNCITONS
  466. ************************************************************************************
  467. ***********************************************************************************/
  468. /***********************************************************************************
  469. * StringToTapeAddress()
  470. *
  471. * Description: Used by the MTF_Write#### functions below. Given a Buffer, an
  472. * MTF_TAPE_ADDRESS struct and the current end of the string storage
  473. * area in the buffer, this function appends the string to the string
  474. * storage area, fills in the MTF_TAPE_ADDRESS struct indicating where
  475. * the string was stored and returns the new end of the string storage
  476. * area accounting for the added string.
  477. ***********************************************************************************/
  478. size_t CMTFApi::StringToTapeAddress(
  479. MTF_TAPE_ADDRESS *pAd, // the mtf tape address structure to fill
  480. BYTE *pBuffer, // the buffer that is being filled
  481. wchar_t *str, // the string to store MTF style in the buffer
  482. size_t uCurrentStorageOffset // the next available point in the buffer for string storage
  483. )
  484. {
  485. // if we have a string,
  486. // - put the size and offset in the MTF_TAPE_ADDRESS structure and then copy
  487. // the string to the pBuffer at the uCurrentStorageOffset'th byte
  488. // otherwise
  489. // - put a zero size and offset in the MTF_TAPE_ADDRESS struct.
  490. // return the new end of the string storage area
  491. if (str)
  492. {
  493. pAd->uSize = (UINT16)wstrsize(str);
  494. pAd->uOffset = (UINT16)uCurrentStorageOffset;
  495. memcpy(pBuffer + uCurrentStorageOffset, str, pAd->uSize);
  496. uCurrentStorageOffset += pAd->uSize;
  497. }
  498. else
  499. {
  500. pAd->uSize = 0;
  501. pAd->uOffset = 0;
  502. }
  503. return uCurrentStorageOffset;
  504. }
  505. /***********************************************************************************
  506. * Align()
  507. *
  508. * Description: Given uSize and an alignment factor, retuns the value
  509. * of the uSize+ pad, where pad is the value necesary to
  510. * get to the next alignment factor.
  511. *
  512. * Returns uSize + pad -- not just pad!
  513. ***********************************************************************************/
  514. size_t CMTFApi::Align(
  515. size_t uSize,
  516. size_t uAlignment)
  517. {
  518. if (uSize % uAlignment)
  519. return uSize - (uSize % uAlignment) + uAlignment;
  520. else
  521. return uSize;
  522. }
  523. /***********************************************************************************
  524. * CalcChecksum()
  525. *
  526. * Description: returns the 16bit XOR sum of the nNum bytes starting at the UINT16
  527. * pointed to by pStartPtr
  528. *
  529. ***********************************************************************************/
  530. UINT16 CMTFApi::CalcChecksum(
  531. BYTE * pStartPtr,
  532. int nNum )
  533. {
  534. UINT16 resultSoFar = 0;
  535. UINT16 UNALIGNED *pCur = (UINT16 *) pStartPtr;
  536. while( nNum-- )
  537. resultSoFar ^= *pCur++ ;
  538. return( resultSoFar ) ;
  539. }
  540. /***********************************************************************************
  541. * CalcChecksumOfStreamData() - (bmd)
  542. *
  543. * Description: returns the 32bit XOR sum of the nNum bytes starting at the UINT64
  544. * pointed to by pStartPtr
  545. *
  546. ***********************************************************************************/
  547. UINT32 CMTFApi::CalcChecksumOfStreamData(
  548. BYTE * pStartPtr,
  549. int nNum )
  550. {
  551. UINT32 resultSoFar = 0;
  552. UINT32 UNALIGNED *pCur = (UINT32 *) pStartPtr;
  553. while( nNum-- )
  554. resultSoFar ^= *pCur++ ;
  555. return( resultSoFar ) ;
  556. }
  557. /***********************************************************************************
  558. ************************************************************************************
  559. ************************************************************************************
  560. **** MTF API STRUCTURE FUNCTIONS
  561. ************************************************************************************
  562. ************************************************************************************
  563. ***********************************************************************************/
  564. /* ==================================================================================
  565. =====================================================================================
  566. Common DBLK: MTF_DBLK_HDR_INFO
  567. =====================================================================================
  568. ================================================================================== */
  569. // Calculates the room that will be taken up in the DBLK by strings and OS specific data
  570. size_t CMTFApi::MTF_DBLK_HDR_INFO_CalcAddDataSize(
  571. MTF_DBLK_HDR_INFO *pSTDInfo
  572. )
  573. {
  574. return pSTDInfo->uOSDataSize;
  575. }
  576. /***********************************************************************************
  577. * MTF_SetDblkHdrDefaults()
  578. * ** MTF API FUNCTION **
  579. ***********************************************************************************/
  580. void CMTFApi::MTF_SetDblkHdrDefaults(
  581. MTF_DBLK_HDR_INFO * pStdInfo
  582. )
  583. {
  584. int i;
  585. for (i = 0; i < 5; ++i)
  586. pStdInfo->acBlockType[i] = 0;
  587. pStdInfo->uBlockAttributes = 0;
  588. pStdInfo->uOSID = 0;
  589. pStdInfo->uOSVersion = 0;
  590. pStdInfo->uDisplayableSize = 0;
  591. pStdInfo->uFormatLogicalAddress = 0;
  592. pStdInfo->uReservedForMBC = 0;
  593. pStdInfo->uSoftwareCompression = MTF_COMPRESS_NONE;
  594. pStdInfo->uControlBlockId = 0;
  595. pStdInfo->pvOSData = 0;
  596. pStdInfo->uOSDataSize = 0;
  597. pStdInfo->uStringType = MTF_STRING_UNICODE_STR;
  598. }
  599. /***********************************************************************************
  600. * MTF_WriteDblkHdrToBuffer()
  601. *
  602. * Description: called by the MTF_Write#####() functions to format the common block
  603. * header to the buffer
  604. * - this also calculates the header check sum and fills it in
  605. *
  606. * Pre: - *puCurrentStorageOffset is the offset at where string and OS Data storage will
  607. * begin in the buffer
  608. * - the size of the buffer has been checked and can hold any info written to it
  609. *
  610. * Post: - *puCurrentStorageOffset is updated to reflect any added strings or storage
  611. *
  612. ***********************************************************************************/
  613. void CMTFApi::MTF_WriteDblkHdrToBuffer(
  614. UINT8 acID[4], // four byte header id to write
  615. UINT16 uOffsetToFirstStream, // the size of the DBLK for which this will be a header
  616. MTF_DBLK_HDR_INFO *psHdrInfo, // the header info struct to use (filled in by client)
  617. BYTE *pBuffer, // the buffer to format to
  618. size_t *puCurrentStorage) // the point in the buffer where string and os data stroage begins
  619. // (this will be updated upon return to reflect added data to storage)
  620. {
  621. MTF_DBLK_HDR *pHDR = 0;
  622. UINT16 uCurrentStorageOffset = 0;
  623. int i;
  624. // - if no *puCurrentStorage, we assume storage starts at
  625. // the end of the on tape MTF_DBLK_HDR structure
  626. if (puCurrentStorage)
  627. uCurrentStorageOffset = (UINT16)*puCurrentStorage;
  628. else
  629. uCurrentStorageOffset = (UINT16)sizeof(MTF_DBLK_HDR);
  630. pHDR = (MTF_DBLK_HDR *) pBuffer;
  631. // write in the four byte DBLK ID
  632. for (i = 0; i < 4; ++i)
  633. pHDR->acBlockType[i] = acID[i];
  634. pHDR->uBlockAttributes = psHdrInfo->uBlockAttributes;
  635. pHDR->uOffsetToFirstStream = uOffsetToFirstStream;
  636. pHDR->uOSID = psHdrInfo->uOSID;
  637. pHDR->uOSVersion = psHdrInfo->uOSVersion;
  638. pHDR->uDisplayableSize = psHdrInfo->uDisplayableSize;
  639. pHDR->uFormatLogicalAddress = psHdrInfo->uFormatLogicalAddress;
  640. pHDR->uReservedForMBC = 0; // must be zero in backup set
  641. pHDR->uSoftwareCompression = psHdrInfo->uSoftwareCompression;
  642. pHDR->uControlBlockId = psHdrInfo->uControlBlockId;
  643. pHDR->sOSSpecificData.uSize = psHdrInfo->uOSDataSize;
  644. // write out the os specific data at the current storage offset and update it
  645. if (psHdrInfo->uOSDataSize)
  646. {
  647. pHDR->sOSSpecificData.uOffset = uCurrentStorageOffset;
  648. memcpy(pBuffer + uCurrentStorageOffset, psHdrInfo->pvOSData, psHdrInfo->uOSDataSize);
  649. uCurrentStorageOffset = uCurrentStorageOffset + psHdrInfo->uOSDataSize;
  650. }
  651. else
  652. {
  653. pHDR->sOSSpecificData.uOffset = 0;
  654. pHDR->sOSSpecificData.uSize = 0;
  655. }
  656. pHDR->uStringType = psHdrInfo->uStringType;
  657. pHDR->uHeaderCheckSum = CalcChecksum(pBuffer, sizeof(MTF_DBLK_HDR) / sizeof(UINT16) - 1);
  658. if (puCurrentStorage)
  659. *puCurrentStorage = uCurrentStorageOffset;
  660. }
  661. void CMTFApi::MTF_DBLK_HDR_INFO_ReadFromBuffer(
  662. MTF_DBLK_HDR_INFO *psHdrInfo,
  663. BYTE *pBuffer)
  664. {
  665. MTF_DBLK_HDR *pHDR = 0;
  666. size_t uCurrentStorageOffset = 0;
  667. int i;
  668. pHDR = (MTF_DBLK_HDR *) pBuffer;
  669. for (i = 0; i < 4; ++i)
  670. psHdrInfo->acBlockType[i] = pHDR->acBlockType[i];
  671. psHdrInfo->acBlockType[4] = 0;
  672. psHdrInfo->uOffsetToFirstStream = pHDR->uOffsetToFirstStream;
  673. psHdrInfo->uBlockAttributes = pHDR->uBlockAttributes ;
  674. psHdrInfo->uOSID = pHDR->uOSID;
  675. psHdrInfo->uOSVersion = pHDR->uOSVersion;
  676. psHdrInfo->uDisplayableSize = pHDR->uDisplayableSize;
  677. psHdrInfo->uFormatLogicalAddress= pHDR->uFormatLogicalAddress;
  678. psHdrInfo->uSoftwareCompression = pHDR->uSoftwareCompression;
  679. psHdrInfo->uControlBlockId = pHDR->uControlBlockId;
  680. psHdrInfo->uOSDataSize = pHDR->sOSSpecificData.uSize;
  681. psHdrInfo->pvOSData = (pBuffer + pHDR->sOSSpecificData.uOffset);
  682. psHdrInfo->uStringType = pHDR->uStringType;
  683. psHdrInfo->uHeaderCheckSum = pHDR->uHeaderCheckSum;
  684. }
  685. /* ==================================================================================
  686. =====================================================================================
  687. TAPE DBLK: MTF_DBLK_TAPE_INFO
  688. =====================================================================================
  689. ================================================================================== */
  690. // Calculates the room that will be taken up in the DBLK by strings and OS specific data
  691. // **NOT INCLUDING THE COMMON DBLK HEADER additional info **
  692. size_t CMTFApi::MTF_DBLK_TAPE_INFO_CalcAddDataSize(
  693. MTF_DBLK_TAPE_INFO *pTapeInfo
  694. )
  695. {
  696. return wstrsize(pTapeInfo->szTapeName) +
  697. wstrsize(pTapeInfo->szTapeDescription) +
  698. wstrsize(pTapeInfo->szTapePassword) +
  699. wstrsize(pTapeInfo->szSoftwareName);
  700. }
  701. /***********************************************************************************
  702. * MTF_SetTAPEDefaults()
  703. * ** MTF API FUNCTION **
  704. ***********************************************************************************/
  705. void CMTFApi::MTF_SetTAPEDefaults(
  706. MTF_DBLK_TAPE_INFO *pTapeInfo
  707. )
  708. {
  709. time_t tTime;
  710. time(&tTime);
  711. pTapeInfo->uTapeFamilyId = 0;
  712. pTapeInfo->uTapeAttributes = 0;
  713. pTapeInfo->uTapeSequenceNumber = 0;
  714. pTapeInfo->uPasswordEncryptionAlgorithm = MTF_PW_ENCRYPT_NONE;
  715. pTapeInfo->uSoftFilemarkBlockSize = 0;
  716. pTapeInfo->uTapeCatalogType = MTF_OTC_NONE; // MTF_OTC_TYPE
  717. pTapeInfo->szTapeName = 0 ;
  718. pTapeInfo->szTapeDescription = 0 ;
  719. pTapeInfo->szTapePassword = 0;
  720. pTapeInfo->szSoftwareName = 0;
  721. pTapeInfo->uAlignmentFactor = MTF_GetAlignmentFactor();
  722. pTapeInfo->uSoftwareVendorId = 0;
  723. pTapeInfo->sTapeDate = MTF_CreateDateTimeFromTM(gmtime(&tTime));
  724. pTapeInfo->uMTFMajorVersion = MTF_FORMAT_VER_MAJOR;
  725. }
  726. /***********************************************************************************
  727. * MTF_WriteTAPEDblk()
  728. * ** MTF API FUNCTION **
  729. ***********************************************************************************/
  730. DWORD CMTFApi::MTF_WriteTAPEDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  731. MTF_DBLK_TAPE_INFO *psTapeInfo,
  732. BYTE *pBuffer,
  733. size_t nBufferSize,
  734. size_t *pnSizeUsed)
  735. {
  736. UINT16 uOffsetToFirstStream;
  737. //
  738. // Figure the size of the entire DBLK & make sure we have room
  739. //
  740. uOffsetToFirstStream = (UINT16) (sizeof(MTF_DBLK_TAPE) +
  741. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo) +
  742. MTF_DBLK_TAPE_INFO_CalcAddDataSize(psTapeInfo));
  743. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  744. if (nBufferSize < uOffsetToFirstStream)
  745. {
  746. if (pnSizeUsed)
  747. *pnSizeUsed = uOffsetToFirstStream;
  748. return MTF_ERROR_BUFFER_TOO_SMALL;
  749. }
  750. memset(pBuffer, 0, uOffsetToFirstStream);
  751. //
  752. // write the header and then fill in the stuff from this info struct
  753. //
  754. {
  755. MTF_DBLK_TAPE *pTape = 0;
  756. size_t uCurrentStorageOffset = 0;
  757. uCurrentStorageOffset = sizeof(MTF_DBLK_TAPE);
  758. MTF_WriteDblkHdrToBuffer(
  759. (UINT8 *)(char *)MTF_ID_TAPE,
  760. uOffsetToFirstStream,
  761. psHdrInfo,
  762. pBuffer,
  763. &uCurrentStorageOffset);
  764. pTape = (MTF_DBLK_TAPE *) pBuffer;
  765. pTape->uTapeFamilyId = psTapeInfo->uTapeFamilyId;
  766. pTape->uTapeAttributes = psTapeInfo->uTapeAttributes;
  767. pTape->uTapeSequenceNumber = psTapeInfo->uTapeSequenceNumber;
  768. pTape->uPasswordEncryptionAlgorithm = psTapeInfo->uPasswordEncryptionAlgorithm;
  769. pTape->uSoftFilemarkBlockSize = psTapeInfo->uSoftFilemarkBlockSize;
  770. pTape->uTapeCatalogType = psTapeInfo->uTapeCatalogType;
  771. uCurrentStorageOffset = StringToTapeAddress(&pTape->sTapeName, pBuffer, psTapeInfo->szTapeName, uCurrentStorageOffset);
  772. uCurrentStorageOffset = StringToTapeAddress(&pTape->sTapeDescription, pBuffer, psTapeInfo->szTapeDescription, uCurrentStorageOffset);
  773. uCurrentStorageOffset = StringToTapeAddress(&pTape->sTapePassword, pBuffer, psTapeInfo->szTapePassword, uCurrentStorageOffset);
  774. uCurrentStorageOffset = StringToTapeAddress(&pTape->sSoftware_name, pBuffer, psTapeInfo->szSoftwareName, uCurrentStorageOffset);
  775. pTape->uAlignmentFactor = psTapeInfo->uAlignmentFactor;
  776. pTape->uSoftwareVendorId = psTapeInfo->uSoftwareVendorId;
  777. pTape->sTapeDate = psTapeInfo->sTapeDate;
  778. pTape->uMTFMajorVersion = psTapeInfo->uMTFMajorVersion;
  779. if (pnSizeUsed)
  780. *pnSizeUsed = uOffsetToFirstStream;
  781. }
  782. return MTF_ERROR_NONE;
  783. }
  784. /***********************************************************************************
  785. * MTF_ReadTAPEDblk()
  786. * ** MTF API FUNCTION **
  787. ***********************************************************************************/
  788. DWORD CMTFApi::MTF_ReadTAPEDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  789. MTF_DBLK_TAPE_INFO *psTapeInfo,
  790. BYTE *pBuffer)
  791. {
  792. MTF_DBLK_TAPE *pTape = 0;
  793. ClearStrings();
  794. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  795. pTape = (MTF_DBLK_TAPE *) pBuffer;
  796. psTapeInfo->uTapeFamilyId = pTape->uTapeFamilyId;
  797. psTapeInfo->uTapeAttributes = pTape->uTapeAttributes;
  798. psTapeInfo->uTapeSequenceNumber = pTape->uTapeSequenceNumber;
  799. psTapeInfo->uPasswordEncryptionAlgorithm = pTape->uPasswordEncryptionAlgorithm;
  800. psTapeInfo->uSoftFilemarkBlockSize = pTape->uSoftFilemarkBlockSize;
  801. psTapeInfo->uTapeCatalogType = pTape->uTapeCatalogType;
  802. psTapeInfo->uAlignmentFactor = pTape->uAlignmentFactor;
  803. psTapeInfo->uSoftwareVendorId = pTape->uSoftwareVendorId;
  804. psTapeInfo->sTapeDate = pTape->sTapeDate;
  805. psTapeInfo->uMTFMajorVersion = pTape->uMTFMajorVersion;
  806. psTapeInfo->szTapeName = MakeString((wchar_t UNALIGNED *) (pBuffer + pTape->sTapeName.uOffset), pTape->sTapeName.uSize);
  807. psTapeInfo->szTapeDescription = MakeString((wchar_t UNALIGNED *) (pBuffer + pTape->sTapeDescription.uOffset), pTape->sTapeDescription.uSize);
  808. psTapeInfo->szTapePassword = MakeString((wchar_t UNALIGNED *) (pBuffer + pTape->sTapePassword.uOffset), pTape->sTapePassword.uSize);
  809. psTapeInfo->szSoftwareName = MakeString((wchar_t UNALIGNED *) (pBuffer + pTape->sSoftware_name.uOffset), pTape->sSoftware_name.uSize);
  810. if ( !psTapeInfo->szTapeName || !psTapeInfo->szTapeDescription || !psTapeInfo->szTapePassword || !psTapeInfo->szSoftwareName)
  811. return MTF_OUT_OF_MEMORY;
  812. return MTF_ERROR_NONE;
  813. }
  814. /* ==================================================================================
  815. =====================================================================================
  816. SSET DBLK: MTF_DBLK_SSET_INFO
  817. =====================================================================================
  818. ================================================================================== */
  819. // Calculates the room that will be taken up in the DBLK by strings and OS specific data
  820. // **NOT INCLUDING THE COMMON DBLK HEADER additional info **
  821. size_t CMTFApi::MTF_DBLK_SSET_INFO_CalcAddDataSize(
  822. MTF_DBLK_SSET_INFO *pSSETInfo
  823. )
  824. {
  825. return wstrsize(pSSETInfo->szDataSetName)
  826. + wstrsize(pSSETInfo->szDataSetDescription)
  827. + wstrsize(pSSETInfo->szDataSetPassword)
  828. + wstrsize(pSSETInfo->szUserName);
  829. }
  830. /***********************************************************************************
  831. * MTF_SetSSETDefaults()
  832. * ** MTF API FUNCTION **
  833. ***********************************************************************************/
  834. void CMTFApi::MTF_SetSSETDefaults(
  835. MTF_DBLK_SSET_INFO *pSSETInfo
  836. )
  837. {
  838. time_t tTime;
  839. time(&tTime);
  840. pSSETInfo->uSSETAttributes = 0;
  841. pSSETInfo->uPasswordEncryptionAlgorithm = MTF_PW_ENCRYPT_NONE;
  842. pSSETInfo->uDataEncryptionAlgorithm = MTF_DATA_ENCRYPT_NONE;
  843. pSSETInfo->uSoftwareVendorId = 0;
  844. pSSETInfo->uDataSetNumber = 0;
  845. pSSETInfo->szDataSetName = 0 ;
  846. pSSETInfo->szDataSetDescription = 0 ;
  847. pSSETInfo->szDataSetPassword = 0 ;
  848. pSSETInfo->szUserName = 0 ;
  849. pSSETInfo->uPhysicalBlockAddress = 0;
  850. pSSETInfo->sMediaWriteDate = MTF_CreateDateTimeFromTM(gmtime(&tTime));
  851. pSSETInfo->uSoftwareVerMjr = 0;
  852. pSSETInfo->uSoftwareVerMnr = 0;
  853. pSSETInfo->uTimeZone = MTF_LOCAL_TZ;
  854. pSSETInfo->uMTFMinorVer = MTF_FORMAT_VER_MINOR;
  855. pSSETInfo->uTapeCatalogVersion = MTF_OTC_NONE; // MTF_OTC_VERSION
  856. }
  857. /***********************************************************************************
  858. * MTF_WriteSSETDblk()
  859. * ** MTF API FUNCTION **
  860. ***********************************************************************************/
  861. DWORD CMTFApi::MTF_WriteSSETDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  862. MTF_DBLK_SSET_INFO *psSSETInfo,
  863. BYTE *pBuffer,
  864. size_t nBufferSize,
  865. size_t *pnSizeUsed)
  866. {
  867. UINT16 uOffsetToFirstStream;
  868. //
  869. // Figure the size of the entire DBLK & make sure we have room
  870. //
  871. uOffsetToFirstStream = (UINT16) (sizeof(MTF_DBLK_SSET) +
  872. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo) +
  873. MTF_DBLK_SSET_INFO_CalcAddDataSize(psSSETInfo));
  874. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  875. if (nBufferSize < uOffsetToFirstStream)
  876. {
  877. if (pnSizeUsed)
  878. *pnSizeUsed = uOffsetToFirstStream;
  879. return MTF_ERROR_BUFFER_TOO_SMALL;
  880. }
  881. memset(pBuffer, 0, uOffsetToFirstStream);
  882. {
  883. MTF_DBLK_SSET *psSSET = 0;
  884. size_t uCurrentStorageOffset = 0;
  885. uCurrentStorageOffset = sizeof(MTF_DBLK_SSET);
  886. MTF_WriteDblkHdrToBuffer(
  887. (UINT8 *)(char *)MTF_ID_SSET,
  888. uOffsetToFirstStream,
  889. psHdrInfo,
  890. pBuffer,
  891. &uCurrentStorageOffset);
  892. psSSET = (MTF_DBLK_SSET *) pBuffer;
  893. psSSET->uSSETAttributes = psSSETInfo->uSSETAttributes;
  894. psSSET->uPasswordEncryptionAlgorithm = psSSETInfo->uPasswordEncryptionAlgorithm;
  895. psSSET->uDataEncryptionAlgorithm = psSSETInfo->uDataEncryptionAlgorithm;
  896. psSSET->uSoftwareVendorId = psSSETInfo->uSoftwareVendorId;
  897. psSSET->uDataSetNumber = psSSETInfo->uDataSetNumber;
  898. uCurrentStorageOffset = StringToTapeAddress(&psSSET->sDataSetName, pBuffer, psSSETInfo->szDataSetName, uCurrentStorageOffset);
  899. uCurrentStorageOffset = StringToTapeAddress(&psSSET->sDataSetDescription, pBuffer, psSSETInfo->szDataSetDescription, uCurrentStorageOffset);
  900. uCurrentStorageOffset = StringToTapeAddress(&psSSET->sDataSetPassword, pBuffer, psSSETInfo->szDataSetPassword, uCurrentStorageOffset);
  901. uCurrentStorageOffset = StringToTapeAddress(&psSSET->sUserName, pBuffer, psSSETInfo->szUserName, uCurrentStorageOffset);
  902. psSSET->uPhysicalBlockAddress = psSSETInfo->uPhysicalBlockAddress;
  903. psSSET->sMediaWriteDate = psSSETInfo->sMediaWriteDate;
  904. psSSET->uSoftwareVerMjr = psSSETInfo->uSoftwareVerMjr;
  905. psSSET->uSoftwareVerMnr = psSSETInfo->uSoftwareVerMnr;
  906. psSSET->uTimeZone = psSSETInfo->uTimeZone;
  907. psSSET->uMTFMinorVer = psSSETInfo->uMTFMinorVer;
  908. psSSET->uTapeCatalogVersion = psSSETInfo->uTapeCatalogVersion;
  909. if (pnSizeUsed)
  910. *pnSizeUsed = uOffsetToFirstStream;
  911. }
  912. return MTF_ERROR_NONE;
  913. }
  914. /***********************************************************************************
  915. * MTF_ReadSSETDblk()
  916. * ** MTF API FUNCTION **
  917. ***********************************************************************************/
  918. DWORD CMTFApi::MTF_ReadSSETDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  919. MTF_DBLK_SSET_INFO *psSSETInfo,
  920. BYTE *pBuffer)
  921. {
  922. MTF_DBLK_SSET *psSSET = 0;
  923. ClearStrings();
  924. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  925. psSSET = (MTF_DBLK_SSET *) pBuffer;
  926. psSSETInfo->uSSETAttributes = psSSET->uSSETAttributes;
  927. psSSETInfo->uPasswordEncryptionAlgorithm = psSSET->uPasswordEncryptionAlgorithm;
  928. psSSETInfo->uDataEncryptionAlgorithm = psSSET->uDataEncryptionAlgorithm;
  929. psSSETInfo->uSoftwareVendorId = psSSET->uSoftwareVendorId;
  930. psSSETInfo->uDataSetNumber = psSSET->uDataSetNumber;
  931. psSSETInfo->uPhysicalBlockAddress = psSSET->uPhysicalBlockAddress;
  932. psSSETInfo->sMediaWriteDate = psSSET->sMediaWriteDate;
  933. psSSETInfo->uSoftwareVerMjr = psSSET->uSoftwareVerMjr;
  934. psSSETInfo->uSoftwareVerMnr = psSSET->uSoftwareVerMnr;
  935. psSSETInfo->uTimeZone = psSSET->uTimeZone;
  936. psSSETInfo->uMTFMinorVer = psSSET->uMTFMinorVer;
  937. psSSETInfo->uTapeCatalogVersion = psSSET->uTapeCatalogVersion;
  938. psSSETInfo->szDataSetName = MakeString((wchar_t UNALIGNED *) (pBuffer + psSSET->sDataSetName.uOffset), psSSET->sDataSetName.uSize);
  939. psSSETInfo->szDataSetDescription = MakeString((wchar_t UNALIGNED *) (pBuffer + psSSET->sDataSetDescription.uOffset), psSSET->sDataSetDescription.uSize);
  940. psSSETInfo->szDataSetPassword = MakeString((wchar_t UNALIGNED *) (pBuffer + psSSET->sDataSetPassword.uOffset), psSSET->sDataSetPassword.uSize);
  941. psSSETInfo->szUserName = MakeString((wchar_t UNALIGNED *) (pBuffer + psSSET->sUserName.uOffset), psSSET->sUserName.uSize);
  942. if ( !psSSETInfo->szDataSetName || !psSSETInfo->szDataSetDescription || !psSSETInfo->szDataSetPassword || !psSSETInfo->szUserName )
  943. return MTF_OUT_OF_MEMORY;
  944. return MTF_ERROR_NONE;
  945. }
  946. /* ==================================================================================
  947. =====================================================================================
  948. VOLB DBLK: MTF_DBLK_VOLB_INFO
  949. =====================================================================================
  950. ================================================================================== */
  951. // Calculates the room that will be taken up in the DBLK by strings and OS specific data
  952. // **NOT INCLUDING THE COMMON DBLK HEADER additional info **
  953. size_t CMTFApi::MTF_DBLK_VOLB_INFO_CalcAddDataSize(
  954. MTF_DBLK_VOLB_INFO *pVOLBInfo
  955. )
  956. {
  957. return wstrsize(pVOLBInfo->szDeviceName) +
  958. wstrsize(pVOLBInfo->szVolumeName) +
  959. wstrsize(pVOLBInfo->szMachineName);
  960. }
  961. /***********************************************************************************
  962. * MTF_SetVOLBDefaults()
  963. * ** MTF API FUNCTION **
  964. ***********************************************************************************/
  965. void CMTFApi::MTF_SetVOLBDefaults(MTF_DBLK_VOLB_INFO *pVOLBInfo)
  966. {
  967. time_t tTime;
  968. time(&tTime);
  969. pVOLBInfo->uVolumeAttributes = 0;
  970. pVOLBInfo->szDeviceName = 0 ;
  971. pVOLBInfo->szVolumeName = 0 ;
  972. pVOLBInfo->szMachineName = 0 ;
  973. pVOLBInfo->sMediaWriteDate = MTF_CreateDateTimeFromTM(gmtime(&tTime));;
  974. }
  975. /***********************************************************************************
  976. * MTF_SetVOLBForDevice()
  977. * ** MTF API FUNCTION **
  978. ***********************************************************************************/
  979. void CMTFApi::MTF_SetVOLBForDevice(MTF_DBLK_VOLB_INFO *pVOLBInfo, wchar_t *szDevice)
  980. {
  981. DWORD dwBufSize = MAX_COMPUTERNAME_LENGTH + 1;
  982. wchar_t tempDeviceName[MTF_STRLEN+4];
  983. wcscpy(m_szDeviceName, szDevice);
  984. MTF_SetVOLBDefaults(pVOLBInfo); // initialize
  985. // Determine the format and set the appropriate bit in the VOLB attributes.
  986. if (*(m_szDeviceName+1) == L':') {
  987. // drive letter w/colon format
  988. pVOLBInfo->uVolumeAttributes |= MTF_VOLB_DEV_DRIVE;
  989. }
  990. else if (0 == wcsncmp( m_szDeviceName, L"UNC", 3 )) {
  991. // UNC format
  992. pVOLBInfo->uVolumeAttributes |= MTF_VOLB_DEV_UNC;
  993. }
  994. else {
  995. // operating system specific format
  996. pVOLBInfo->uVolumeAttributes |= MTF_VOLB_DEV_OS_SPEC;
  997. }
  998. // need to prepend \\?\ for the GetVolumeInformation call
  999. wcscpy(tempDeviceName, L"\\\\?\\");
  1000. wcscat(tempDeviceName, m_szDeviceName);
  1001. GetVolumeInformationW(tempDeviceName, m_szVolumeName, MTF_STRLEN, 0, 0, 0, 0, 0);
  1002. GetComputerNameW(m_szMachineName, &dwBufSize);
  1003. pVOLBInfo->szDeviceName = m_szDeviceName;
  1004. pVOLBInfo->szVolumeName = m_szVolumeName;
  1005. pVOLBInfo->szMachineName = m_szMachineName;
  1006. }
  1007. /***********************************************************************************
  1008. * MTF_WriteVOLBDblk()
  1009. * ** MTF API FUNCTION **
  1010. ***********************************************************************************/
  1011. DWORD CMTFApi::MTF_WriteVOLBDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1012. MTF_DBLK_VOLB_INFO *psVOLBInfo,
  1013. BYTE *pBuffer,
  1014. size_t nBufferSize,
  1015. size_t *pnSizeUsed)
  1016. {
  1017. UINT16 uOffsetToFirstStream;
  1018. //
  1019. // Figure the size of the entire DBLK & make sure we have room
  1020. //
  1021. uOffsetToFirstStream = (UINT16) (sizeof(MTF_DBLK_VOLB) +
  1022. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo) +
  1023. MTF_DBLK_VOLB_INFO_CalcAddDataSize(psVOLBInfo));
  1024. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  1025. if (nBufferSize < uOffsetToFirstStream)
  1026. {
  1027. if (pnSizeUsed)
  1028. *pnSizeUsed = uOffsetToFirstStream;
  1029. return MTF_ERROR_BUFFER_TOO_SMALL;
  1030. }
  1031. memset(pBuffer, 0, uOffsetToFirstStream);
  1032. {
  1033. MTF_DBLK_VOLB *psVOLB = 0;
  1034. size_t uCurrentStorageOffset = 0;
  1035. uCurrentStorageOffset = sizeof(MTF_DBLK_VOLB);
  1036. MTF_WriteDblkHdrToBuffer(
  1037. (UINT8 *)(char *)MTF_ID_VOLB,
  1038. uOffsetToFirstStream,
  1039. psHdrInfo,
  1040. pBuffer,
  1041. &uCurrentStorageOffset);
  1042. psVOLB = (MTF_DBLK_VOLB *) pBuffer;
  1043. psVOLB->uVolumeAttributes = psVOLBInfo->uVolumeAttributes;
  1044. uCurrentStorageOffset = StringToTapeAddress(&psVOLB->sDeviceName, pBuffer, psVOLBInfo->szDeviceName, uCurrentStorageOffset);
  1045. uCurrentStorageOffset = StringToTapeAddress(&psVOLB->sVolumeName, pBuffer, psVOLBInfo->szVolumeName, uCurrentStorageOffset);
  1046. uCurrentStorageOffset = StringToTapeAddress(&psVOLB->sMachineName, pBuffer, psVOLBInfo->szMachineName, uCurrentStorageOffset);
  1047. psVOLB->sMediaWriteDate = psVOLBInfo->sMediaWriteDate;
  1048. if (pnSizeUsed)
  1049. *pnSizeUsed = uOffsetToFirstStream;
  1050. }
  1051. return MTF_ERROR_NONE;
  1052. }
  1053. /***********************************************************************************
  1054. * MTF_ReadVOLBDblk()
  1055. * ** MTF API FUNCTION **
  1056. ***********************************************************************************/
  1057. DWORD CMTFApi::MTF_ReadVOLBDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1058. MTF_DBLK_VOLB_INFO *psVOLBInfo,
  1059. BYTE *pBuffer)
  1060. {
  1061. MTF_DBLK_VOLB *psVOLB = 0;
  1062. ClearStrings();
  1063. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  1064. psVOLB = (MTF_DBLK_VOLB *) pBuffer;
  1065. psVOLBInfo->uVolumeAttributes = psVOLB->uVolumeAttributes;
  1066. psVOLBInfo->sMediaWriteDate = psVOLB->sMediaWriteDate;
  1067. psVOLBInfo->szDeviceName = MakeString((wchar_t UNALIGNED *) (pBuffer + psVOLB->sDeviceName.uOffset), psVOLB->sDeviceName.uSize);
  1068. psVOLBInfo->szVolumeName = MakeString((wchar_t UNALIGNED *) (pBuffer + psVOLB->sVolumeName.uOffset), psVOLB->sVolumeName.uSize);
  1069. psVOLBInfo->szMachineName = MakeString((wchar_t UNALIGNED *) (pBuffer + psVOLB->sMachineName.uOffset), psVOLB->sMachineName.uSize);
  1070. if ( !psVOLBInfo->szDeviceName || !psVOLBInfo->szVolumeName || !psVOLBInfo->szMachineName )
  1071. return MTF_OUT_OF_MEMORY;
  1072. return MTF_ERROR_NONE;
  1073. }
  1074. /* ==================================================================================
  1075. =====================================================================================
  1076. DIRB DBLK: MTF_DBLK_DIRB_INFO
  1077. =====================================================================================
  1078. ================================================================================== */
  1079. // Calculates the room that will be taken up in the DBLK by strings and OS specific data
  1080. // **NOT INCLUDING THE COMMON DBLK HEADER additional info **
  1081. size_t CMTFApi::MTF_DBLK_DIRB_INFO_CalcAddDataSize(MTF_DBLK_DIRB_INFO *pDIRBInfo)
  1082. {
  1083. return wstrsize(pDIRBInfo->szDirectoryName);
  1084. }
  1085. /***********************************************************************************
  1086. * MTF_SetDIRBDefaults()
  1087. * ** MTF API FUNCTION **
  1088. ***********************************************************************************/
  1089. void CMTFApi::MTF_SetDIRBDefaults(
  1090. MTF_DBLK_DIRB_INFO *pDIRBInfo
  1091. )
  1092. {
  1093. pDIRBInfo->uDirectoryAttributes = 0;
  1094. pDIRBInfo->sLastModificationDate = MTF_CreateDateNull();
  1095. pDIRBInfo->sCreationDate = MTF_CreateDateNull();
  1096. pDIRBInfo->sBackupDate = MTF_CreateDateNull();
  1097. pDIRBInfo->sLastAccessDate = MTF_CreateDateNull();
  1098. pDIRBInfo->uDirectoryId = 0;
  1099. pDIRBInfo->szDirectoryName = 0 ;
  1100. }
  1101. /***********************************************************************************
  1102. * MTF_SetDIRBFromFindData()
  1103. * ** MTF API FUNCTION **
  1104. ***********************************************************************************/
  1105. void CMTFApi::MTF_SetDIRBFromFindData(
  1106. MTF_DBLK_DIRB_INFO *pDIRBInfo,
  1107. wchar_t *szDirectoryName,
  1108. WIN32_FIND_DATAW *pFindData
  1109. )
  1110. {
  1111. MTF_SetDIRBDefaults(pDIRBInfo); // initialize
  1112. if ( wcslen( szDirectoryName ) < MTF_STRLEN ) {
  1113. wcscpy(m_szDirectoryName, szDirectoryName);
  1114. pDIRBInfo->szDirectoryName = m_szDirectoryName;
  1115. }
  1116. else {
  1117. pDIRBInfo->uDirectoryAttributes |= MTF_DIRB_PATH_IN_STREAM;
  1118. pDIRBInfo->szDirectoryName = 0;
  1119. }
  1120. if (pFindData)
  1121. {
  1122. pDIRBInfo->uDirectoryAttributes |=
  1123. ((pFindData->dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? MTF_DIRB_READ_ONLY : 0)
  1124. | ((pFindData->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? MTF_DIRB_HIDDEN : 0)
  1125. | ((pFindData->dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? MTF_DIRB_SYSTEM : 0)
  1126. | ((pFindData->dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ? MTF_DIRB_MODIFIED : 0);
  1127. pDIRBInfo->sLastModificationDate = MTF_CreateDateTimeFromFileTime(pFindData->ftLastWriteTime);
  1128. pDIRBInfo->sCreationDate = MTF_CreateDateTimeFromFileTime(pFindData->ftCreationTime);
  1129. pDIRBInfo->sLastAccessDate = MTF_CreateDateTimeFromFileTime(pFindData->ftLastAccessTime);
  1130. }
  1131. pDIRBInfo->uDirectoryId = 0;
  1132. }
  1133. /***********************************************************************************
  1134. * MTF_WriteDIRBDblk()
  1135. * ** MTF API FUNCTION **
  1136. ***********************************************************************************/
  1137. DWORD CMTFApi::MTF_WriteDIRBDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1138. MTF_DBLK_DIRB_INFO *psDIRBInfo,
  1139. BYTE *pBuffer,
  1140. size_t nBufferSize,
  1141. size_t *pnSizeUsed)
  1142. {
  1143. UINT16 uOffsetToFirstStream;
  1144. //
  1145. // Figure the size of the entire DBLK & make sure we have room
  1146. //
  1147. uOffsetToFirstStream = (UINT16) (sizeof(MTF_DBLK_DIRB) +
  1148. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo) +
  1149. MTF_DBLK_DIRB_INFO_CalcAddDataSize(psDIRBInfo));
  1150. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  1151. if (nBufferSize < uOffsetToFirstStream)
  1152. {
  1153. if (pnSizeUsed)
  1154. *pnSizeUsed = uOffsetToFirstStream;
  1155. return MTF_ERROR_BUFFER_TOO_SMALL;
  1156. }
  1157. memset(pBuffer, 0, uOffsetToFirstStream);
  1158. {
  1159. MTF_DBLK_DIRB *psDIRB = 0;
  1160. size_t uCurrentStorageOffset = 0;
  1161. uCurrentStorageOffset = sizeof(MTF_DBLK_DIRB);
  1162. MTF_WriteDblkHdrToBuffer(
  1163. (UINT8 *)(char *)MTF_ID_DIRB,
  1164. uOffsetToFirstStream,
  1165. psHdrInfo,
  1166. pBuffer,
  1167. &uCurrentStorageOffset);
  1168. psDIRB = (MTF_DBLK_DIRB *) pBuffer;
  1169. psDIRB->uDirectoryAttributes = psDIRBInfo->uDirectoryAttributes;
  1170. psDIRB->sLastModificationDate = psDIRBInfo->sLastModificationDate;
  1171. psDIRB->sCreationDate = psDIRBInfo->sCreationDate;
  1172. psDIRB->sBackupDate = psDIRBInfo->sBackupDate;
  1173. psDIRB->sLastAccessDate = psDIRBInfo->sLastAccessDate;
  1174. psDIRB->uDirectoryId = psDIRBInfo->uDirectoryId;
  1175. //
  1176. // here, we need to turn the slashes (L'\\') to zeros (L'\0')in the directory name string...
  1177. //
  1178. {
  1179. int i, iLen;
  1180. wchar_t UNALIGNED *szDirectoryName = (wchar_t UNALIGNED *) (pBuffer + uCurrentStorageOffset);
  1181. uCurrentStorageOffset = StringToTapeAddress(&psDIRB->sDirectoryName, pBuffer, psDIRBInfo->szDirectoryName, uCurrentStorageOffset);
  1182. if (psDIRBInfo->szDirectoryName) {
  1183. iLen = wcslen(psDIRBInfo->szDirectoryName);
  1184. } else {
  1185. iLen = 0;
  1186. }
  1187. for (i = 0; i < iLen; ++i)
  1188. if (szDirectoryName[i] == L'\\')
  1189. szDirectoryName[i] = L'\0';
  1190. }
  1191. if (pnSizeUsed)
  1192. *pnSizeUsed = uOffsetToFirstStream;
  1193. }
  1194. return MTF_ERROR_NONE;
  1195. }
  1196. /***********************************************************************************
  1197. * MTF_ReadDIRBDblk()
  1198. * ** MTF API FUNCTION **
  1199. ***********************************************************************************/
  1200. DWORD CMTFApi::MTF_ReadDIRBDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1201. MTF_DBLK_DIRB_INFO *psDIRBInfo,
  1202. BYTE *pBuffer)
  1203. {
  1204. MTF_DBLK_DIRB *psDIRB = 0;
  1205. ClearStrings();
  1206. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  1207. psDIRB = (MTF_DBLK_DIRB *) pBuffer;
  1208. psDIRBInfo->uDirectoryAttributes = psDIRB->uDirectoryAttributes;
  1209. psDIRBInfo->sLastModificationDate = psDIRB->sLastModificationDate;
  1210. psDIRBInfo->sCreationDate = psDIRB->sCreationDate;
  1211. psDIRBInfo->sBackupDate = psDIRB->sBackupDate;
  1212. psDIRBInfo->sLastAccessDate = psDIRB->sLastAccessDate;
  1213. psDIRBInfo->uDirectoryId = psDIRB->uDirectoryId;
  1214. psDIRBInfo->szDirectoryName = NULL;
  1215. //
  1216. // we need to turn the zeros in the directory name back to slashes
  1217. // (there are no terminating \0's in the string -- all \0's are really \\'s
  1218. //
  1219. {
  1220. wchar_t *pTmpBuffer;
  1221. int i;
  1222. pTmpBuffer = (wchar_t *) malloc(psDIRB->sDirectoryName.uSize);
  1223. if (pTmpBuffer) {
  1224. memmove(pTmpBuffer, pBuffer + psDIRB->sDirectoryName.uOffset, psDIRB->sDirectoryName.uSize);
  1225. for (i = 0; i < (int)(psDIRB->sDirectoryName.uSize / sizeof(wchar_t)); ++i)
  1226. if (pTmpBuffer[i] == L'\0')
  1227. pTmpBuffer[i] = L'\\';
  1228. psDIRBInfo->szDirectoryName = MakeString(pTmpBuffer, psDIRB->sDirectoryName.uSize);
  1229. free(pTmpBuffer);
  1230. }
  1231. }
  1232. if ( !psDIRBInfo->szDirectoryName )
  1233. return MTF_OUT_OF_MEMORY;
  1234. return MTF_ERROR_NONE;
  1235. }
  1236. /* ==================================================================================
  1237. =====================================================================================
  1238. FILE DBLK: MTF_DBLK_FILE_INFO
  1239. =====================================================================================
  1240. ================================================================================== */
  1241. // Calculates the room that will be taken up in the DBLK by strings and OS specific data
  1242. // **NOT INCLUDING THE COMMON DBLK HEADER additional info **
  1243. size_t CMTFApi::MTF_DBLK_FILE_INFO_CalcAddDataSize(MTF_DBLK_FILE_INFO *pFILEInfo)
  1244. {
  1245. return wstrsize(pFILEInfo->szFileName);
  1246. }
  1247. /***********************************************************************************
  1248. * MTF_SetFILEDefaults()
  1249. * ** MTF API FUNCTION **
  1250. ***********************************************************************************/
  1251. void CMTFApi::MTF_SetFILEDefaults(MTF_DBLK_FILE_INFO *pFILEInfo)
  1252. {
  1253. pFILEInfo->uFileAttributes = 0;
  1254. pFILEInfo->sLastModificationDate = MTF_CreateDateNull();
  1255. pFILEInfo->sCreationDate = MTF_CreateDateNull();
  1256. pFILEInfo->sBackupDate = MTF_CreateDateNull();
  1257. pFILEInfo->sLastAccessDate = MTF_CreateDateNull();
  1258. pFILEInfo->uDirectoryId = 0;
  1259. pFILEInfo->uFileId = 0;
  1260. pFILEInfo->szFileName = 0;
  1261. }
  1262. /***********************************************************************************
  1263. * MTF_SetFILEFromFindData()
  1264. * ** MTF API FUNCTION **
  1265. ***********************************************************************************/
  1266. void CMTFApi::MTF_SetFILEFromFindData(MTF_DBLK_FILE_INFO *pFILEInfo, WIN32_FIND_DATAW *pFindData)
  1267. {
  1268. time_t tTime;
  1269. time(&tTime);
  1270. MTF_SetFILEDefaults(pFILEInfo); // initialize
  1271. wcscpy(m_szFileName, pFindData->cFileName);
  1272. pFILEInfo->uFileAttributes =
  1273. ((pFindData->dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? MTF_FILE_READ_ONLY : 0)
  1274. | ((pFindData->dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ? MTF_FILE_HIDDEN : 0)
  1275. | ((pFindData->dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) ? MTF_FILE_SYSTEM : 0)
  1276. | ((pFindData->dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) ? MTF_FILE_MODIFIED : 0) ;
  1277. pFILEInfo->sLastModificationDate = MTF_CreateDateTimeFromFileTime(pFindData->ftLastWriteTime);
  1278. pFILEInfo->sCreationDate = MTF_CreateDateTimeFromFileTime(pFindData->ftCreationTime);
  1279. pFILEInfo->sLastAccessDate = MTF_CreateDateTimeFromFileTime(pFindData->ftLastAccessTime);
  1280. pFILEInfo->uDirectoryId = 0;
  1281. pFILEInfo->uFileId = 0;
  1282. pFILEInfo->szFileName = m_szFileName;
  1283. pFILEInfo->uDisplaySize = MTF_CreateUINT64(pFindData->nFileSizeLow, pFindData->nFileSizeHigh);
  1284. }
  1285. /***********************************************************************************
  1286. * MTF_WriteFILEDblk()
  1287. * ** MTF API FUNCTION **
  1288. ***********************************************************************************/
  1289. DWORD CMTFApi::MTF_WriteFILEDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1290. MTF_DBLK_FILE_INFO *psFILEInfo,
  1291. BYTE *pBuffer,
  1292. size_t nBufferSize,
  1293. size_t *pnSizeUsed)
  1294. {
  1295. UINT16 uOffsetToFirstStream;
  1296. //
  1297. // Figure the size of the entire DBLK & make sure we have room
  1298. //
  1299. uOffsetToFirstStream = (UINT16) (sizeof(MTF_DBLK_FILE) +
  1300. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo) +
  1301. MTF_DBLK_FILE_INFO_CalcAddDataSize(psFILEInfo));
  1302. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  1303. if (nBufferSize < uOffsetToFirstStream)
  1304. {
  1305. if (pnSizeUsed)
  1306. *pnSizeUsed = uOffsetToFirstStream;
  1307. return MTF_ERROR_BUFFER_TOO_SMALL;
  1308. }
  1309. memset(pBuffer, 0, uOffsetToFirstStream);
  1310. {
  1311. MTF_DBLK_FILE *psFILE = 0;
  1312. size_t uCurrentStorageOffset = 0;
  1313. uCurrentStorageOffset = sizeof(MTF_DBLK_FILE);
  1314. psHdrInfo->uDisplayableSize = psFILEInfo->uDisplaySize;
  1315. MTF_WriteDblkHdrToBuffer(
  1316. (UINT8 *)(char *)MTF_ID_FILE,
  1317. uOffsetToFirstStream,
  1318. psHdrInfo,
  1319. pBuffer,
  1320. &uCurrentStorageOffset);
  1321. psFILE = (MTF_DBLK_FILE *) pBuffer;
  1322. psFILE->uFileAttributes = psFILEInfo->uFileAttributes;
  1323. psFILE->sLastModificationDate = psFILEInfo->sLastModificationDate;
  1324. psFILE->sCreationDate = psFILEInfo->sCreationDate;
  1325. psFILE->sBackupDate = psFILEInfo->sBackupDate;
  1326. psFILE->sLastAccessDate = psFILEInfo->sLastAccessDate;
  1327. psFILE->uDirectoryId = psFILEInfo->uDirectoryId;
  1328. psFILE->uFileId = psFILEInfo->uFileId;
  1329. uCurrentStorageOffset = StringToTapeAddress(&psFILE->sFileName, pBuffer, psFILEInfo->szFileName, uCurrentStorageOffset);
  1330. if (pnSizeUsed)
  1331. *pnSizeUsed = uOffsetToFirstStream;
  1332. }
  1333. return MTF_ERROR_NONE;
  1334. }
  1335. /***********************************************************************************
  1336. * MTF_ReadFILEDblk()
  1337. * ** MTF API FUNCTION **
  1338. ***********************************************************************************/
  1339. DWORD CMTFApi::MTF_ReadFILEDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1340. MTF_DBLK_FILE_INFO *psFILEInfo,
  1341. BYTE *pBuffer)
  1342. {
  1343. MTF_DBLK_FILE *psFILE = 0;
  1344. ClearStrings();
  1345. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  1346. psFILE = (MTF_DBLK_FILE *) pBuffer;
  1347. psFILEInfo->uFileAttributes = psFILE->uFileAttributes;
  1348. psFILEInfo->sLastModificationDate = psFILE->sLastModificationDate;
  1349. psFILEInfo->sCreationDate = psFILE->sCreationDate;
  1350. psFILEInfo->sBackupDate = psFILE->sBackupDate;
  1351. psFILEInfo->sLastAccessDate = psFILE->sLastAccessDate;
  1352. psFILEInfo->uDirectoryId = psFILE->uDirectoryId;
  1353. psFILEInfo->uFileId = psFILE->uFileId;
  1354. psFILEInfo->szFileName = MakeString((wchar_t UNALIGNED *) (pBuffer + psFILE->sFileName.uOffset), psFILE->sFileName.uSize);
  1355. if ( !psFILEInfo->szFileName )
  1356. return MTF_OUT_OF_MEMORY;
  1357. return MTF_ERROR_NONE;
  1358. }
  1359. /* ==================================================================================
  1360. =====================================================================================
  1361. CFIL DBLK: MTF_DBLK_CFIL_INFO
  1362. =====================================================================================
  1363. ================================================================================== */
  1364. /***********************************************************************************
  1365. * MTF_SetCFILDefaults()
  1366. * ** MTF API FUNCTION **
  1367. ***********************************************************************************/
  1368. void CMTFApi::MTF_SetCFILDefaults(
  1369. MTF_DBLK_CFIL_INFO *pCFILInfo
  1370. )
  1371. {
  1372. pCFILInfo->uCFileAttributes = MTF_CFIL_UNREADABLE_BLK;
  1373. pCFILInfo->uDirectoryId = 0;
  1374. pCFILInfo->uFileId = 0;
  1375. pCFILInfo->uStreamOffset = 0;
  1376. pCFILInfo->uCorruptStreamNumber = 0;
  1377. }
  1378. /***********************************************************************************
  1379. * MTF_WriteCFILDblk()
  1380. * ** MTF API FUNCTION **
  1381. ***********************************************************************************/
  1382. DWORD CMTFApi::MTF_WriteCFILDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1383. MTF_DBLK_CFIL_INFO *psCFILInfo,
  1384. BYTE *pBuffer,
  1385. size_t nBufferSize,
  1386. size_t *pnSizeUsed)
  1387. {
  1388. UINT16 uOffsetToFirstStream;
  1389. //
  1390. // Figure the size of the entire DBLK & make sure we have room
  1391. //
  1392. uOffsetToFirstStream = (UINT16) (sizeof(MTF_DBLK_HDR) +
  1393. sizeof(MTF_DBLK_CFIL) +
  1394. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo));
  1395. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  1396. if (nBufferSize < uOffsetToFirstStream)
  1397. {
  1398. if (pnSizeUsed)
  1399. *pnSizeUsed = uOffsetToFirstStream;
  1400. return MTF_ERROR_BUFFER_TOO_SMALL;
  1401. }
  1402. memset(pBuffer, 0, uOffsetToFirstStream);
  1403. {
  1404. MTF_DBLK_CFIL_INFO *psCFIL = 0;
  1405. size_t uCurrentStorageOffset = 0;
  1406. uCurrentStorageOffset = sizeof(MTF_DBLK_HDR) + sizeof(MTF_DBLK_CFIL);
  1407. MTF_WriteDblkHdrToBuffer(
  1408. (UINT8 *)(char *)MTF_ID_CFIL,
  1409. uOffsetToFirstStream,
  1410. psHdrInfo,
  1411. pBuffer,
  1412. &uCurrentStorageOffset);
  1413. psCFIL = (MTF_DBLK_CFIL_INFO *) (pBuffer + sizeof(MTF_DBLK_HDR));
  1414. *psCFIL = *psCFILInfo;
  1415. if (pnSizeUsed)
  1416. *pnSizeUsed = uOffsetToFirstStream;
  1417. }
  1418. return MTF_ERROR_NONE;
  1419. }
  1420. /***********************************************************************************
  1421. * MTF_ReadCFILDblk()
  1422. * ** MTF API FUNCTION **
  1423. ***********************************************************************************/
  1424. DWORD CMTFApi::MTF_ReadCFILDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1425. MTF_DBLK_CFIL_INFO *psCFILInfo,
  1426. BYTE *pBuffer)
  1427. {
  1428. MTF_DBLK_CFIL *psCFIL = 0;
  1429. ClearStrings();
  1430. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  1431. psCFIL = (MTF_DBLK_CFIL_INFO *) (pBuffer + sizeof(MTF_DBLK_HDR));
  1432. *psCFILInfo = *psCFIL;
  1433. return MTF_ERROR_NONE;
  1434. }
  1435. /* ==================================================================================
  1436. =====================================================================================
  1437. ESPB DBLK
  1438. =====================================================================================
  1439. ================================================================================== */
  1440. /***********************************************************************************
  1441. * MTF_WriteESPBDblk()
  1442. * ** MTF API FUNCTION **
  1443. ***********************************************************************************/
  1444. DWORD CMTFApi::MTF_WriteESPBDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1445. BYTE *pBuffer,
  1446. size_t nBufferSize,
  1447. size_t *pnSizeUsed)
  1448. {
  1449. UINT16 uOffsetToFirstStream;
  1450. //
  1451. // Figure the size of the entire DBLK & make sure we have room
  1452. //
  1453. uOffsetToFirstStream = (UINT16) (sizeof(MTF_DBLK_HDR) +
  1454. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo));
  1455. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  1456. if (nBufferSize < uOffsetToFirstStream) {
  1457. if (pnSizeUsed) {
  1458. *pnSizeUsed = uOffsetToFirstStream;
  1459. }
  1460. return MTF_ERROR_BUFFER_TOO_SMALL;
  1461. }
  1462. memset(pBuffer, 0, uOffsetToFirstStream);
  1463. MTF_WriteDblkHdrToBuffer(
  1464. (UINT8 *)(char *)MTF_ID_ESPB,
  1465. uOffsetToFirstStream,
  1466. psHdrInfo,
  1467. pBuffer,
  1468. 0);
  1469. if (pnSizeUsed)
  1470. *pnSizeUsed = uOffsetToFirstStream;
  1471. return MTF_ERROR_NONE;
  1472. }
  1473. /***********************************************************************************
  1474. * MTF_ReadESPBDblk()
  1475. * ** MTF API FUNCTION **
  1476. ***********************************************************************************/
  1477. DWORD CMTFApi::MTF_ReadESPBDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1478. BYTE *pBuffer)
  1479. {
  1480. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  1481. return MTF_ERROR_NONE;
  1482. }
  1483. /* ==================================================================================
  1484. =====================================================================================
  1485. End of Set DBLK (ESET)
  1486. =====================================================================================
  1487. ================================================================================== */
  1488. /***********************************************************************************
  1489. * MTF_SetESETDefaults()
  1490. * ** MTF API FUNCTION **
  1491. ***********************************************************************************/
  1492. void CMTFApi::MTF_SetESETDefaults(MTF_DBLK_ESET_INFO *pESETInfo)
  1493. {
  1494. time_t tTime;
  1495. time(&tTime);
  1496. pESETInfo->uESETAttributes = 0;
  1497. pESETInfo->uNumberOfCorrupFiles = 0;
  1498. pESETInfo->uSetMapPBA = 0;
  1499. pESETInfo->uFileDetailPBA = 0;
  1500. pESETInfo->uFDDTapeSequenceNumber = 0;
  1501. pESETInfo->uDataSetNumber = 0;
  1502. pESETInfo->sMediaWriteDate = MTF_CreateDateTimeFromTM(gmtime(&tTime));
  1503. }
  1504. /***********************************************************************************
  1505. * MTF_WriteESETDblk()
  1506. * ** MTF API FUNCTION **
  1507. ***********************************************************************************/
  1508. DWORD CMTFApi::MTF_WriteESETDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1509. MTF_DBLK_ESET_INFO *psESETInfo,
  1510. BYTE *pBuffer,
  1511. size_t nBufferSize,
  1512. size_t *pnSizeUsed)
  1513. {
  1514. UINT16 uOffsetToFirstStream;
  1515. //
  1516. // Figure the size of the entire DBLK & make sure we have room
  1517. //
  1518. uOffsetToFirstStream = (UINT16) (sizeof(MTF_DBLK_ESET) +
  1519. sizeof(MTF_DBLK_HDR) +
  1520. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo));
  1521. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  1522. if (nBufferSize < uOffsetToFirstStream)
  1523. {
  1524. if (pnSizeUsed)
  1525. *pnSizeUsed = uOffsetToFirstStream;
  1526. return MTF_ERROR_BUFFER_TOO_SMALL;
  1527. }
  1528. memset(pBuffer, 0, uOffsetToFirstStream);
  1529. {
  1530. MTF_DBLK_ESET_INFO *psESET = 0;
  1531. size_t uCurrentStorageOffset = 0;
  1532. uCurrentStorageOffset = sizeof(MTF_DBLK_ESET) + sizeof(MTF_DBLK_HDR);
  1533. MTF_WriteDblkHdrToBuffer(
  1534. (UINT8 *)(char *)MTF_ID_ESET,
  1535. uOffsetToFirstStream,
  1536. psHdrInfo,
  1537. pBuffer,
  1538. &uCurrentStorageOffset);
  1539. psESET = (MTF_DBLK_ESET_INFO *) (pBuffer + sizeof(MTF_DBLK_HDR));
  1540. *psESET = *psESETInfo;
  1541. if (pnSizeUsed)
  1542. *pnSizeUsed = uOffsetToFirstStream;
  1543. }
  1544. return MTF_ERROR_NONE;
  1545. }
  1546. /***********************************************************************************
  1547. * MTF_ReadESETDblk()
  1548. * ** MTF API FUNCTION **
  1549. ***********************************************************************************/
  1550. DWORD CMTFApi::MTF_ReadESETDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1551. MTF_DBLK_ESET_INFO *psESETInfo,
  1552. BYTE *pBuffer)
  1553. {
  1554. MTF_DBLK_ESET *psESET = 0;
  1555. ClearStrings();
  1556. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  1557. psESET = (MTF_DBLK_ESET_INFO *) (pBuffer + sizeof(MTF_DBLK_HDR));
  1558. *psESETInfo = *psESET;
  1559. return MTF_ERROR_NONE;
  1560. }
  1561. /* ==================================================================================
  1562. =====================================================================================
  1563. End of Set DBLK (EOTM)
  1564. =====================================================================================
  1565. ================================================================================== */
  1566. /***********************************************************************************
  1567. * MTF_SetEOTMDefaults()
  1568. * ** MTF API FUNCTION **
  1569. ***********************************************************************************/
  1570. void CMTFApi::MTF_SetEOTMDefaults(MTF_DBLK_EOTM_INFO *pEOTMInfo)
  1571. {
  1572. pEOTMInfo->uLastESETPBA = 0;
  1573. }
  1574. /***********************************************************************************
  1575. * MTF_WriteEOTMDblk()
  1576. * ** MTF API FUNCTION **
  1577. ***********************************************************************************/
  1578. DWORD CMTFApi::MTF_WriteEOTMDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1579. MTF_DBLK_EOTM_INFO *psEOTMInfo,
  1580. BYTE *pBuffer,
  1581. size_t nBufferSize,
  1582. size_t *pnSizeUsed)
  1583. {
  1584. UINT16 uOffsetToFirstStream;
  1585. //
  1586. // Figure the size of the entire DBLK & make sure we have room
  1587. //
  1588. uOffsetToFirstStream = (UINT16) (sizeof(MTF_DBLK_EOTM_INFO) +
  1589. sizeof(MTF_DBLK_HDR) +
  1590. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo));
  1591. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  1592. if (nBufferSize < uOffsetToFirstStream)
  1593. {
  1594. if (pnSizeUsed)
  1595. *pnSizeUsed = uOffsetToFirstStream;
  1596. return MTF_ERROR_BUFFER_TOO_SMALL;
  1597. }
  1598. memset(pBuffer, 0, uOffsetToFirstStream);
  1599. {
  1600. MTF_DBLK_EOTM_INFO *psEOTM = 0;
  1601. size_t uCurrentStorageOffset = 0;
  1602. uCurrentStorageOffset = sizeof(MTF_DBLK_HDR) + sizeof(MTF_DBLK_EOTM);
  1603. MTF_WriteDblkHdrToBuffer(
  1604. (UINT8 *)(char *)MTF_ID_EOTM,
  1605. uOffsetToFirstStream,
  1606. psHdrInfo,
  1607. pBuffer,
  1608. &uCurrentStorageOffset);
  1609. psEOTM = (MTF_DBLK_EOTM_INFO *) (pBuffer + sizeof(MTF_DBLK_HDR));
  1610. *psEOTM = *psEOTMInfo;
  1611. if (pnSizeUsed)
  1612. *pnSizeUsed = uOffsetToFirstStream;
  1613. }
  1614. return MTF_ERROR_NONE;
  1615. }
  1616. /***********************************************************************************
  1617. * MTF_ReadEOTMDblk()
  1618. * ** MTF API FUNCTION **
  1619. ***********************************************************************************/
  1620. DWORD CMTFApi::MTF_ReadEOTMDblk( MTF_DBLK_HDR_INFO *psHdrInfo,
  1621. MTF_DBLK_EOTM_INFO *psEOTMInfo,
  1622. BYTE *pBuffer)
  1623. {
  1624. MTF_DBLK_EOTM *psEOTM = 0;
  1625. ClearStrings();
  1626. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  1627. psEOTM = (MTF_DBLK_EOTM_INFO *) (pBuffer + sizeof(MTF_DBLK_HDR));
  1628. *psEOTMInfo = *psEOTM;
  1629. return MTF_ERROR_NONE;
  1630. }
  1631. /* ==================================================================================
  1632. =====================================================================================
  1633. Soft Filemark (SFMB)
  1634. =====================================================================================
  1635. ================================================================================== */
  1636. /***********************************************************************************
  1637. * MTF_CreateSFMB() - (bmd)
  1638. * ** MTF API FUNCTION **
  1639. ***********************************************************************************/
  1640. size_t CMTFApi::MTF_GetMaxSoftFilemarkEntries(size_t nBlockSize)
  1641. {
  1642. size_t n;
  1643. if (0 == nBlockSize || nBlockSize % 512) {
  1644. return 0;
  1645. }
  1646. // The SFMB fills the entire block.
  1647. // Calculate the total number of entries that fit within a block
  1648. // such that MTF_DBLK_HDR + MTF_DBLK_SFMB + (n-1 elements) < nBlockSize
  1649. n = (nBlockSize - sizeof(MTF_DBLK_HDR) - sizeof(MTF_DBLK_SFMB) + sizeof(UINT32))/sizeof(UINT32);
  1650. return n;
  1651. }
  1652. /***********************************************************************************
  1653. * MTF_InsertSoftFilemark() - (bmd)
  1654. * ** MTF API FUNCTION **
  1655. ***********************************************************************************/
  1656. void CMTFApi::MTF_InsertSoftFilemark(MTF_DBLK_SFMB_INFO *psSoftInfo,
  1657. UINT32 pba)
  1658. {
  1659. size_t n;
  1660. size_t bytesToShift;
  1661. // We insert a filemark entry by shifting all the entries down. The one closest BOM
  1662. // eventually drop out of the array.
  1663. if (psSoftInfo) {
  1664. n = psSoftInfo->uNumberOfFilemarkEntries;
  1665. bytesToShift = psSoftInfo->uFilemarkEntriesUsed * sizeof(UINT32);
  1666. // So we don't overwrite memory.
  1667. bytesToShift -= (psSoftInfo->uFilemarkEntriesUsed < psSoftInfo->uNumberOfFilemarkEntries) ? 0 : sizeof(UINT32);
  1668. memmove(&psSoftInfo->uFilemarkArray[1], &psSoftInfo->uFilemarkArray[0], bytesToShift);
  1669. psSoftInfo->uFilemarkArray[0] = pba;
  1670. if (psSoftInfo->uFilemarkEntriesUsed < psSoftInfo->uNumberOfFilemarkEntries) {
  1671. psSoftInfo->uFilemarkEntriesUsed++;
  1672. }
  1673. }
  1674. }
  1675. /***********************************************************************************
  1676. * MTF_WriteSFMBDblk() - (bmd)
  1677. * ** MTF API FUNCTION **
  1678. ***********************************************************************************/
  1679. DWORD CMTFApi::MTF_WriteSFMBDblk(MTF_DBLK_HDR_INFO *psHdrInfo,
  1680. MTF_DBLK_SFMB_INFO *psSoftInfo,
  1681. BYTE *pBuffer,
  1682. size_t nBufferSize,
  1683. size_t *pnSizeUsed)
  1684. {
  1685. UINT16 uOffsetToFirstStream;
  1686. size_t sizeOfSFMB;
  1687. if (NULL == psHdrInfo || NULL == psSoftInfo || NULL == pBuffer || NULL == pnSizeUsed || 0 == nBufferSize) {
  1688. return ERROR_INVALID_PARAMETER;
  1689. }
  1690. // Code assumes sizeof(MTF_DBLK_SFMB_INFO) == sizeof(MTF_DBLK_SFMB)
  1691. if (sizeof(MTF_DBLK_SFMB_INFO) != sizeof(MTF_DBLK_SFMB)) {
  1692. return ERROR_INVALID_FUNCTION;
  1693. }
  1694. //
  1695. // Figure the size of the entire DBLK & make sure we have room
  1696. //
  1697. sizeOfSFMB = sizeof(MTF_DBLK_SFMB) + (psSoftInfo->uNumberOfFilemarkEntries-1)*sizeof(UINT32);
  1698. uOffsetToFirstStream = (UINT16) (sizeOfSFMB +
  1699. sizeof(MTF_DBLK_HDR) +
  1700. MTF_DBLK_HDR_INFO_CalcAddDataSize(psHdrInfo));
  1701. uOffsetToFirstStream = (UINT16)Align(uOffsetToFirstStream, 4);
  1702. if (nBufferSize < uOffsetToFirstStream)
  1703. {
  1704. if (pnSizeUsed)
  1705. *pnSizeUsed = uOffsetToFirstStream;
  1706. return MTF_ERROR_BUFFER_TOO_SMALL;
  1707. }
  1708. memset(pBuffer, 0, uOffsetToFirstStream);
  1709. {
  1710. MTF_DBLK_SFMB_INFO *psSFMB = 0;
  1711. size_t uCurrentStorageOffset = 0;
  1712. uCurrentStorageOffset = sizeof(MTF_DBLK_HDR) + sizeOfSFMB;
  1713. MTF_WriteDblkHdrToBuffer(
  1714. (UINT8 *)(char *)MTF_ID_SFMB,
  1715. uOffsetToFirstStream,
  1716. psHdrInfo,
  1717. pBuffer,
  1718. &uCurrentStorageOffset);
  1719. psSFMB = (MTF_DBLK_SFMB *) (pBuffer + sizeof(MTF_DBLK_HDR));
  1720. // Need a deep copy since MTF_DBLK_SFMB_INFO holds a placeholder for the array.
  1721. memcpy(psSFMB, psSoftInfo, sizeOfSFMB);
  1722. if (pnSizeUsed) {
  1723. *pnSizeUsed = uOffsetToFirstStream;
  1724. }
  1725. }
  1726. return MTF_ERROR_NONE;
  1727. }
  1728. /***********************************************************************************
  1729. * MTF_ReadSFMBDblk() - (bmd)
  1730. * ** MTF API FUNCTION **
  1731. ***********************************************************************************/
  1732. DWORD CMTFApi::MTF_ReadSFMBDblk(MTF_DBLK_HDR_INFO *psHdrInfo,
  1733. MTF_DBLK_SFMB_INFO *psSoftInfo,
  1734. BYTE *pBuffer)
  1735. {
  1736. MTF_DBLK_SFMB *psSFMB = 0;
  1737. size_t sizeOfSFMB;
  1738. if (NULL == psHdrInfo || NULL == psSoftInfo || NULL == pBuffer) {
  1739. return ERROR_INVALID_PARAMETER;
  1740. }
  1741. // Code assumes sizeof(MTF_DBLK_SFMB_INFO) == sizeof(MTF_DBLK_SFMB)
  1742. if (sizeof(MTF_DBLK_SFMB_INFO) != sizeof(MTF_DBLK_SFMB)) {
  1743. return ERROR_INVALID_FUNCTION;
  1744. }
  1745. ClearStrings();
  1746. MTF_DBLK_HDR_INFO_ReadFromBuffer(psHdrInfo, pBuffer);
  1747. psSFMB = (MTF_DBLK_SFMB *) (pBuffer + sizeof(MTF_DBLK_HDR));
  1748. // Need a deep copy since MTF_DBLK_SFMB_INFO holds a placeholder for the array.
  1749. sizeOfSFMB = sizeof(MTF_DBLK_SFMB) + (psSFMB->uNumberOfFilemarkEntries-1)*sizeof(UINT32);
  1750. memcpy(psSoftInfo, psSFMB, sizeOfSFMB);
  1751. return MTF_ERROR_NONE;
  1752. }
  1753. /* ==================================================================================
  1754. =====================================================================================
  1755. STREAM HEADER
  1756. =====================================================================================
  1757. ================================================================================== */
  1758. /***********************************************************************************
  1759. * MTF_SetSTREAMDefaults()
  1760. * ** MTF API FUNCTION **
  1761. ***********************************************************************************/
  1762. void CMTFApi::MTF_SetSTREAMDefaults(MTF_STREAM_INFO *pSTREAMInfo, char *szId)
  1763. {
  1764. memcpy(pSTREAMInfo->acStreamId, szId, 4);
  1765. pSTREAMInfo->uStreamFileSystemAttributes = 0;
  1766. pSTREAMInfo->uStreamTapeFormatAttributes = 0;
  1767. pSTREAMInfo->uStreamLength = 0;
  1768. pSTREAMInfo->uDataEncryptionAlgorithm = 0;
  1769. pSTREAMInfo->uDataCompressionAlgorithm = 0;
  1770. pSTREAMInfo->uCheckSum = 0;
  1771. }
  1772. /***********************************************************************************
  1773. * MTF_SetSTREAMFromStreamId()
  1774. * ** MTF API FUNCTION **
  1775. ***********************************************************************************/
  1776. void CMTFApi::MTF_SetSTREAMFromStreamId(
  1777. MTF_STREAM_INFO *pSTREAMInfo,
  1778. WIN32_STREAM_ID *pStreamId,
  1779. size_t nIDHeaderSize
  1780. )
  1781. {
  1782. // From Steve DeVos, Seagate:
  1783. // > BACKUP_INVALID and BACKUP_LINK will never be returned from BackupRead.
  1784. // >
  1785. // > -Steve
  1786. //
  1787. // TODO: MTF_NT_ENCRYPTED_STREAM "NTED"; These retrieved by NT Encyption APIs
  1788. // TODO: MTF_NT_QUOTA_STREAM "NTQU"; These retrieved by NT Quota APIs
  1789. MTF_SetSTREAMDefaults(pSTREAMInfo, "UNKN");
  1790. if (pStreamId->dwStreamId == BACKUP_DATA)
  1791. memcpy(pSTREAMInfo->acStreamId, "STAN", 4);
  1792. else if (pStreamId->dwStreamId == BACKUP_EA_DATA)
  1793. memcpy(pSTREAMInfo->acStreamId, "NTEA", 4);
  1794. else if (pStreamId->dwStreamId == BACKUP_SECURITY_DATA)
  1795. memcpy(pSTREAMInfo->acStreamId, "NACL", 4);
  1796. else if (pStreamId->dwStreamId == BACKUP_ALTERNATE_DATA)
  1797. memcpy(pSTREAMInfo->acStreamId, "ADAT", 4);
  1798. else if (pStreamId->dwStreamId == BACKUP_OBJECT_ID)
  1799. memcpy(pSTREAMInfo->acStreamId, "NTOI", 4);
  1800. else if (pStreamId->dwStreamId == BACKUP_REPARSE_DATA)
  1801. memcpy(pSTREAMInfo->acStreamId, "NTRP", 4);
  1802. else if (pStreamId->dwStreamId == BACKUP_SPARSE_BLOCK)
  1803. memcpy(pSTREAMInfo->acStreamId, "SPAR", 4);
  1804. else {
  1805. pSTREAMInfo->uStreamFileSystemAttributes |= MTF_STREAM_IS_NON_PORTABLE;
  1806. }
  1807. if (pStreamId->dwStreamAttributes & STREAM_MODIFIED_WHEN_READ)
  1808. pSTREAMInfo->uStreamFileSystemAttributes |= MTF_STREAM_MODIFIED_BY_READ;
  1809. if (pStreamId->dwStreamAttributes & STREAM_CONTAINS_SECURITY)
  1810. pSTREAMInfo->uStreamFileSystemAttributes |= MTF_STREAM_CONTAINS_SECURITY;
  1811. if (pStreamId->dwStreamAttributes & STREAM_SPARSE_ATTRIBUTE)
  1812. pSTREAMInfo->uStreamFileSystemAttributes |= MTF_STREAM_IS_SPARSE;
  1813. pSTREAMInfo->uStreamTapeFormatAttributes = 0;
  1814. pSTREAMInfo->uStreamLength = MTF_CreateUINT64(pStreamId->Size.LowPart, pStreamId->Size.HighPart) + nIDHeaderSize;
  1815. pSTREAMInfo->uDataEncryptionAlgorithm = 0;
  1816. pSTREAMInfo->uDataCompressionAlgorithm = 0;
  1817. pSTREAMInfo->uCheckSum = 0;
  1818. }
  1819. /***********************************************************************************
  1820. * MTF_SetStreamIdFromSTREAM() - (bmd)
  1821. * ** MTF API FUNCTION **
  1822. ***********************************************************************************/
  1823. void CMTFApi::MTF_SetStreamIdFromSTREAM(
  1824. WIN32_STREAM_ID *pStreamId,
  1825. MTF_STREAM_INFO *pSTREAMInfo,
  1826. size_t nIDHeaderSize
  1827. )
  1828. {
  1829. UNREFERENCED_PARAMETER(nIDHeaderSize);
  1830. memset( pStreamId, 0, sizeof( WIN32_STREAM_ID ) );
  1831. if (0 == memcmp(pSTREAMInfo->acStreamId, "STAN", 4))
  1832. pStreamId->dwStreamId = BACKUP_DATA;
  1833. else if (0 == memcmp(pSTREAMInfo->acStreamId, "NTEA", 4))
  1834. pStreamId->dwStreamId = BACKUP_EA_DATA;
  1835. else if (0 == memcmp(pSTREAMInfo->acStreamId, "NACL", 4))
  1836. pStreamId->dwStreamId = BACKUP_SECURITY_DATA;
  1837. else if (0 == memcmp(pSTREAMInfo->acStreamId, "ADAT", 4))
  1838. pStreamId->dwStreamId = BACKUP_ALTERNATE_DATA;
  1839. else if (0 == memcmp(pSTREAMInfo->acStreamId, "NTOI", 4))
  1840. pStreamId->dwStreamId = BACKUP_OBJECT_ID;
  1841. else if (0 == memcmp(pSTREAMInfo->acStreamId, "NTRP", 4))
  1842. pStreamId->dwStreamId = BACKUP_REPARSE_DATA;
  1843. else if (0 == memcmp(pSTREAMInfo->acStreamId, "SPAR", 4))
  1844. pStreamId->dwStreamId = BACKUP_SPARSE_BLOCK;
  1845. else {
  1846. pStreamId->dwStreamId = BACKUP_INVALID;
  1847. }
  1848. pStreamId->dwStreamAttributes = STREAM_NORMAL_ATTRIBUTE;
  1849. if (pSTREAMInfo->uStreamFileSystemAttributes & MTF_STREAM_MODIFIED_BY_READ)
  1850. pStreamId->dwStreamAttributes |= STREAM_MODIFIED_WHEN_READ;
  1851. if (pSTREAMInfo->uStreamFileSystemAttributes & MTF_STREAM_CONTAINS_SECURITY)
  1852. pStreamId->dwStreamAttributes |= STREAM_CONTAINS_SECURITY;
  1853. if (pSTREAMInfo->uStreamFileSystemAttributes & MTF_STREAM_IS_SPARSE)
  1854. pStreamId->dwStreamAttributes |= STREAM_SPARSE_ATTRIBUTE;
  1855. // TODO: Handle named data streams (size of name and in MTF stream)
  1856. // ? How do I know ?
  1857. pStreamId->Size.LowPart = (DWORD)((pSTREAMInfo->uStreamLength << 32) >>32);
  1858. pStreamId->Size.HighPart = (DWORD)(pSTREAMInfo->uStreamLength >> 32);
  1859. }
  1860. /***********************************************************************************
  1861. * MTF_WriteStreamHeader()
  1862. * ** MTF API FUNCTION **
  1863. ***********************************************************************************/
  1864. DWORD CMTFApi::MTF_WriteStreamHeader(MTF_STREAM_INFO *psStreamInfo,
  1865. BYTE *pBuffer,
  1866. size_t nBufferSize,
  1867. size_t *pnSizeUsed)
  1868. {
  1869. psStreamInfo->uCheckSum = CalcChecksum((BYTE *) psStreamInfo, sizeof(MTF_STREAM_INFO) / sizeof(UINT16) - 1);
  1870. if (nBufferSize < sizeof(MTF_STREAM_INFO))
  1871. {
  1872. if (pnSizeUsed)
  1873. *pnSizeUsed = sizeof(MTF_STREAM_INFO);
  1874. return MTF_ERROR_BUFFER_TOO_SMALL;
  1875. }
  1876. memset(pBuffer, 0, sizeof(MTF_STREAM_INFO));
  1877. *((MTF_STREAM_INFO *) pBuffer) = *psStreamInfo;
  1878. if (pnSizeUsed)
  1879. *pnSizeUsed = sizeof(MTF_STREAM_INFO);
  1880. return MTF_ERROR_NONE;
  1881. }
  1882. /***********************************************************************************
  1883. * MTF_WriteNameStream() - (bmd)
  1884. * ** MTF API FUNCTION **
  1885. ***********************************************************************************/
  1886. DWORD CMTFApi::MTF_WriteNameStream(
  1887. char *szType,
  1888. wchar_t *szName,
  1889. BYTE *pBuffer,
  1890. size_t nBufferSize,
  1891. size_t *pnSizeUsed)
  1892. {
  1893. MTF_STREAM_INFO sStream;
  1894. UINT16 uOffsetToCSUMStream;
  1895. UINT16 uOffsetToNextStream;
  1896. size_t nBufUsed;
  1897. UINT16 nameSize;
  1898. UINT32 nameChecksum;
  1899. //
  1900. // Figure the size of the entire Name stream including trailing CSUM and make sure we have room.
  1901. //
  1902. nameSize = (UINT16)wstrsize(szName); // including terminating '\0'
  1903. uOffsetToCSUMStream = sizeof(MTF_STREAM_INFO) + nameSize;
  1904. uOffsetToCSUMStream = (UINT16)Align(uOffsetToCSUMStream, 4);
  1905. uOffsetToNextStream = uOffsetToCSUMStream;
  1906. uOffsetToNextStream += sizeof(MTF_STREAM_INFO) + 4; // includes 4 byte CSUM data
  1907. uOffsetToNextStream = (UINT16)Align(uOffsetToNextStream, 4);
  1908. if (nBufferSize < uOffsetToNextStream) {
  1909. return MTF_ERROR_BUFFER_TOO_SMALL;
  1910. }
  1911. memset(pBuffer, 0, uOffsetToNextStream);
  1912. MTF_SetSTREAMDefaults(&sStream, szType);
  1913. sStream.uStreamLength = nameSize;
  1914. sStream.uStreamTapeFormatAttributes |= MTF_STREAM_CHECKSUMED;
  1915. MTF_WriteStreamHeader(&sStream, pBuffer, nBufferSize, &nBufUsed);
  1916. memcpy(pBuffer + nBufUsed, szName, nameSize);
  1917. if ( 0 == memcmp(sStream.acStreamId, "PNAM", 4) ) {
  1918. //
  1919. // here, we need to turn the slashes (L'\\') to zeros (L'\0')in the directory name string...
  1920. //
  1921. int i, iLen;
  1922. wchar_t UNALIGNED *szDirectoryName = (wchar_t UNALIGNED *) (pBuffer + nBufUsed);
  1923. if (szDirectoryName) {
  1924. iLen = ua_wcslen(szDirectoryName);
  1925. } else {
  1926. iLen = 0;
  1927. }
  1928. for (i = 0; i < iLen; ++i)
  1929. if (szDirectoryName[i] == L'\\')
  1930. szDirectoryName[i] = L'\0';
  1931. }
  1932. // For Name streams, we always tack on a CSUM
  1933. nameChecksum = CalcChecksumOfStreamData(pBuffer + nBufUsed, nameSize / sizeof(UINT32) + 1);
  1934. MTF_SetSTREAMDefaults(&sStream, MTF_CHECKSUM_STREAM);
  1935. sStream.uStreamLength = sizeof(nameChecksum);
  1936. MTF_WriteStreamHeader(&sStream, pBuffer + uOffsetToCSUMStream, nBufferSize, &nBufUsed);
  1937. memcpy(pBuffer + uOffsetToCSUMStream + nBufUsed, &nameChecksum, sizeof(nameChecksum));
  1938. if (pnSizeUsed)
  1939. *pnSizeUsed = uOffsetToNextStream;
  1940. return MTF_ERROR_NONE;
  1941. }
  1942. /***********************************************************************************
  1943. * MTF_ReadStreamHeader()
  1944. * ** MTF API FUNCTION **
  1945. ***********************************************************************************/
  1946. DWORD CMTFApi::MTF_ReadStreamHeader(MTF_STREAM_INFO *psStreamInfo,
  1947. BYTE *pBuffer)
  1948. {
  1949. *psStreamInfo = *((MTF_STREAM_INFO *) pBuffer);
  1950. return MTF_ERROR_NONE;
  1951. }