NTMSLABL.CPP

/* 
* This is a part of the Microsoft Source Code Samples.
*
*This sample code shows the usage of some portions
*of the NTMS API.
*
*Return codes are, for the most part, not checked in
*this code. See the Programmer's reference for error
*return information.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
* Copyright 1997 - 1998 Microsoft Corporation. All Rights Reserved.
*/
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include <time.h>
#include <rpc.h>
#include <NtmsMli.h>
#include "mtf_defs.h"
#include "ntmsapilabel.h"

WORD XORCheckSum(WORD *, DWORD ) ;

void writeOmid (HANDLE hDevice, BYTE *Buffer, DWORD *BufferSizePtr)
{
// local variables ...
DWORD nError = NO_ERROR ;
MTF_TapeDBLK *plbl ;
BYTE LabelBuffer[1024] ;
time_t CurrentTime;
struct tm *GMTime ;
wchar_t DateString[10] ;
wchar_t TimeString[12] ;
wchar_t SoftwareName[80] ;
wchar_t TapeName[80] ;
WORD nSize ;
WORD nTapeNameLength, nSoftwareNameLength ;
BOOL nRetCode ;
DWORD nBytesWritten ;
BYTE TapeDate[4] ;
void *pTapeName, *pSoftwareName ;

// create and fill in the MTF media label ...
memset (LabelBuffer, 0, 1024) ;
plbl = (MTF_TapeDBLK *) LabelBuffer ;
strncpy ((char *)plbl->BlockHeader.BlockType, MTF_TapeDBLKLabel, MTF_TapeDBLKLabelSize) ;
//plbl->BlockHeader.BlockAttributes = 0x30000 ;
//plbl->BlockHeader.OffsetToFirstStream = 0x400 ;
//plbl->BlockHeader.OSID = 0xe ;
plbl->BlockHeader.StringType = UNICODE_STR ;
plbl->BlockHeader.HeaderCheckSum =
XORCheckSum((WORD *)&plbl->BlockHeader,
sizeof(plbl->BlockHeader) - sizeof(plbl->BlockHeader.HeaderCheckSum)) ;
//plbl->TapeSequenceNumber = 1 ;
//plbl->TapeCatalogType = 1 ;// MTF_OTC_TYPE
//plbl->AlignmentFactor = 1024 ;// 1k alignment factor ...
//plbl->MTFMajorVersion = 1 ;// MTF_FORMAT_VER_MAJOR

// get the current time ...
time(&CurrentTime);

// create the date and time string ...
GMTime = gmtime(&CurrentTime) ;
wcsftime (DateString, 10, L"%m/%d/%y", GMTime) ;
wcsftime (TimeString, 12, L"%I:%M:%S %p", GMTime) ;

// fill in the Tape Name and the Software Name fields ...
swprintf(SoftwareName, L"%s (APIDEMO.EXE) Version 1.0 Rev 5",
MTF_MediaLabelType_NT_ApiDemo);
swprintf(TapeName, L"Tape created on %s", DateString);

// copy the TapeName and the SoftwareName into the Media Label that we are creating ...
nSize = sizeof (MTF_TapeDBLK) ;
nTapeNameLength = wcslen (TapeName) ;
plbl->TapeName.Size = nTapeNameLength * 2 ;// strings are Unicode (i.e. 2 byte chars)
plbl->TapeName.Offset = nSize ;// size of the MTF_TapeDBLK ...
pTapeName = (void *) ((DWORD) plbl + (DWORD) plbl->TapeName.Offset) ;
wcsncpy ((wchar_t *) pTapeName, TapeName, nTapeNameLength) ;

// setup the SoftwareName ... copy the SoftwareName into the label ...
nSoftwareNameLength = wcslen(SoftwareName) ;plbl->SoftwareName.Size = nSoftwareNameLength * 2 ; // strings are Unicode (i.e. 2 byte chars)
plbl->SoftwareName.Offset = nSize + plbl->TapeName.Size ;
pSoftwareName = (void *) ((DWORD) plbl + (DWORD) plbl->SoftwareName.Offset) ;
wcsncpy ((wchar_t *) pSoftwareName, SoftwareName, nSoftwareNameLength) ;

// fill in the TapeDate and MediaID fields ...
TapeDate[0] = plbl->TapeDate.Time[1] ;
TapeDate[1] = plbl->TapeDate.Time[2] ;
TapeDate[2] = plbl->TapeDate.Time[3] ;
TapeDate[3] = plbl->TapeDate.Time[4] ;
memcpy ((void *)&(plbl->TapeFamilyID), (void *) TapeDate, 4) ;

// set the tape label bit
plbl->TapeAttributes = TAPE_MEDIA_LABEL_BIT;

// write the data out to the media ...
nRetCode = WriteFile (hDevice, (void *) plbl, 1024,
&nBytesWritten, NULL) ;
if (nRetCode == FALSE)
{
nError = GetLastError() ;
}
else
{
if (BufferSizePtr != NULL)
{
if (NULL != Buffer)
{
if (*BufferSizePtr >= nBytesWritten)
{
*BufferSizePtr = nBytesWritten;
memcpy(Buffer, (void *)plbl, *BufferSizePtr);
}
}
else
{
*BufferSizePtr = 0;
}
}
}

// return
return;
}

// Routine to compute the WORD X-OR CheckSum of the bytes for the number of bytes
// specified.
WORD XORCheckSum(WORD *pBuffer, DWORD nBytes)
{
WORD RetVal = 0;
for (DWORD i = 0; i < nBytes / sizeof(WORD); i++)
{
RetVal ^= pBuffer[i];
}

return RetVal;
}