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.

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