/*
* This is a part of the Microsoft Source Code Samples.
* Copyright 1996 - 1998 Microsoft Corporation.
* All rights reserved.
*
*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 "ntmsmll.h"
#include "mtf_defs.h"
//#include <crt\\wchar.h>
//////////////////////////////
// PROTOTYPES //
//////////////////////////////
DWORD GetMediaGuid(wchar_t *pDescription, WORD size, GUID &gMediaGuid);
DWORD ClaimMediaLabel(const BYTE * const pBuffer, const DWORD nBufferSize,
MediaLabelInfo * const pLabelInfo)
{
// local variables
DWORD nError = NO_ERROR ;
MTF_TapeDBLK *pLabel ;
void *pTapeName, *pSoftwareName ;
pLabel = (MTF_TapeDBLK *) pBuffer ;
if (strncmp ((char *) pLabel->BlockHeader.BlockType, MTF_TapeDBLKLabel,
MTF_TapeDBLKLabelSize) == 0)
{
// this is an MTF tape ... make sure the TapeName and SoftwareName
// strings actually have data in them ...
if ((pLabel->TapeName.Size != 0) && (pLabel->SoftwareName.Size != 0))
{
// there are strings in the MTF label ... find the strings that we need ...
pTapeName = (void *) ((DWORD) pLabel + (DWORD) pLabel->TapeName.Offset) ;
pSoftwareName = (void *) ((DWORD) pLabel + (DWORD) pLabel->SoftwareName.Offset) ;
// if this MTF tape uses Unicode strings
if (pLabel->BlockHeader.StringType == UNICODE_STR)
{
// if this is an NTMS API Demo tape ...
if (wcsncmp ((wchar_t *) pSoftwareName, MTF_MediaLabelType_NT_ApiDemo,
MTF_MediaLabelType_NT_ApiDemoSize) == 0)
{
// this is an NTMS API Demo tape ... copy the info into the LabelInfo ...
wcsncpy(pLabelInfo->LabelType, (wchar_t *) pSoftwareName, MTF_MediaLabelType_NT_ApiDemoSize) ;
pLabelInfo->LabelType[MTF_MediaLabelType_NT_ApiDemoSize] = '\0' ;
// Copy the App Description
// copying unicode string ... divide the size in half ...
wcsncpy(pLabelInfo->LabelAppDescr, (wchar_t *) pTapeName, (pLabel->TapeName.Size / 2));
pLabelInfo->LabelAppDescr[(pLabel->TapeName.Size / 2)] = '\0' ;
// if this tape contains a real description/label
if ((TAPE_MEDIA_LABEL_BIT & pLabel->TapeAttributes) &&
(0 < pLabel->TapeDescription.Size))
{
void *pDescription = (void *) ((DWORD)pLabel +
(DWORD)pLabel->TapeDescription.Offset);
GUID gMediaGuid;
DWORD result = NO_ERROR;
result = GetMediaGuid((wchar_t *)pDescription,
pLabel->TapeDescription.Size,
gMediaGuid);
if (NO_ERROR == result)
{
// We found a good GUID in the description, use it
pLabelInfo->LabelIDSize = sizeof(gMediaGuid);
memcpy(pLabelInfo->LabelID,
&gMediaGuid,
pLabelInfo->LabelIDSize);
return NO_ERROR;
}
}
pLabelInfo->LabelIDSize = sizeof (pLabel->TapeFamilyID) ;
memcpy(pLabelInfo->LabelID, &pLabel->TapeFamilyID, pLabelInfo->LabelIDSize);
return NO_ERROR ;
}
}
else // strings are in ANSI form ...
{
nError = ERROR_BAD_FORMAT ;
}
}
}
// media label was not recognized ... return ERROR_BAD_FORMAT ...
return ERROR_BAD_FORMAT ;
}
DWORD MaxMediaLabel (DWORD * const pMaxSize)
{
// local variables
DWORD nError = NO_ERROR ;
// set the max size for the seagate label ...
*pMaxSize = 1024 ;
return nError ;
}
#define HEX_0 L'0'
#define HEX_9 L'9'
#define HEX_A L'A'
#define HEX_F L'F'
#define OUR_STRING wchar_t*
#define OUR_BAR L'|'
#define OUR_BRACE L'{'
DWORD ConvertHex(OUR_STRING str,int length)
{
DWORD value = 0;
OUR_STRING instr = str;
for(int i=0;i<length;i++){
value = value << 4;
if(instr[i] >= HEX_A && instr[i] <= HEX_F){
value += instr[i]-'A'+10;
} else if(instr[i] >= HEX_0 && instr[i] <= HEX_9){
value += instr[i]-HEX_0;
}
}
return value;
}
//
// TODO - This is the exact same code as in NTBackup.cpp
// Need to make it a .lib somewhere!!!
//
DWORD GetMediaGuid(OUR_STRING pDescription, WORD size, GUID &gMediaGuid)
{
//
// pDescription is a string delimited by "|" characters
// The GUID we are looking for is the 8th field and has
// the form "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
// we need to cram this into a GUID
//
//
int numChars = size / sizeof(wchar_t);
//
// Find the 7th "|"
//
WORD BarNum=0;
int CheckChar = 0;
while ((BarNum < 7) && (CheckChar < numChars))
{
if (pDescription[CheckChar++] == OUR_BAR)
{
BarNum++;
}
}
if (!(
(7 == BarNum) &&
(CheckChar < numChars) &&
(pDescription[CheckChar] == OUR_BRACE))
)
{
return ERROR_BAD_FORMAT;
}
OUR_STRING pId = &pDescription[CheckChar];
pId++;
gMediaGuid.Data1 = ConvertHex(pId,8);
pId += 9;
gMediaGuid.Data2 = (WORD)ConvertHex(pId,4);
pId += 5;
gMediaGuid.Data3 = (WORD)ConvertHex(pId,4);
pId += 5;
int i;
for(i=0;i<2;i++){
gMediaGuid.Data4[i] = (BYTE)ConvertHex(pId,2);
pId += 2;
}
pId++;
for(i=2;i<8;i++){
gMediaGuid.Data4[i] = (BYTE)ConvertHex(pId,2);
pId += 2;
}
pId++;
return NO_ERROR;
}