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.
 
 
 
 
 
 

1018 lines
20 KiB

/*++
Copyright (C) Microsoft Corporation, 1999 - 1999
Module Name:
Conversion
Abstract:
This module contains simple conversion routines.
Author:
Doug Barlow (dbarlow) 6/20/1999
Notes:
?Notes?
--*/
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "stdafx.h"
#include "ByteBuffer.h"
#include "Conversion.h"
static BOOL
GuidFromString(
LPCTSTR szGuid,
LPGUID pGuid);
/*++
ConstructRequest:
This routine builds an APDU Request.
Arguments:
bCla supplies the Class byte
cIns supplies the Instance byte
bP1 supplies P1
bP2 supplies P2
bfData supplies the data
wLe supplies the expected return length
dwFlags supplies any special processing flags:
APDU_EXTENDED_LC - Force an extended value for Lc
APDU_EXTENDED_LE - Force an externded value for Le
APDU_MAXIMUM_LE - Request the maximum Le value
bfApdu receives the constructed APDU
Return Value:
None
Throws:
Errors are thrown as HRESULT status codes
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/26/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("ConstructRequest")
void
ConstructRequest(
IN BYTE bCla,
IN BYTE bIns,
IN BYTE bP1,
IN BYTE bP2,
IN CBuffer &bfData,
IN WORD wLe,
IN DWORD dwFlags,
OUT CBuffer &bfApdu)
{
WORD wLc;
BOOL fExtended;
BYTE b, rgLen[2];
//
// Quick prep work
//
if (0xffff < bfData.Length())
throw (HRESULT)E_INVALIDARG;
wLc = (WORD)bfData.Length();
bfApdu.Presize(4 + 3 + 3 + wLc); // Worst case
fExtended = (0 != (dwFlags & APDU_EXTENDED_LENGTH))
|| (0xff < wLe)
|| (0xff < wLc);
//
// Fill in the buffer with the easy stuff.
//
bfApdu.Set(&bCla, 1);
bfApdu.Append(&bIns, 1);
bfApdu.Append(&bP1, 1);
bfApdu.Append(&bP2, 1);
//
// Is there data to be sent?
//
if (0 != wLc)
{
if (fExtended)
{
LocalToNet(rgLen, wLc);
bfApdu.Append((LPCBYTE)"", 1); // Append a zero byte
bfApdu.Append(rgLen, 2);
}
else
{
b = LeastSignificantByte(wLc);
bfApdu.Append(&b, 1);
}
bfApdu.Append(bfData.Access(), wLc);
}
//
// Do we expect data back?
//
if ((0 != wLe) || (0 != (dwFlags & APDU_MAXIMUM_LE)))
{
if (fExtended)
{
if (0 == wLc)
bfApdu.Append((LPCBYTE)"", 1); // Append a zero byte
LocalToNet(rgLen, wLe);
bfApdu.Append(rgLen, 2);
}
else
{
b = LeastSignificantByte(wLe);
bfApdu.Append(&b, 1);
}
}
}
/*++
ParseRequest:
This routine parses an APDU into it's components.
Arguments:
bfApdu supplies the APDU to be parsed.
pbCla receives the Class
pbIns receives the Instance
pbP1 receives P1
pbP2 receives P2
pbfData receives the data
pwLc receives the supplied data length
pwLe receives the expected length
pdwFlags receives the construction flags
APDU_EXTENDED_LC - There was an extended value for Lc
APDU_EXTENDED_LE - There was an externded value for Le
APDU_MAXIMUM_LE - There was a maximum Le value
Return Value:
None
Throws:
Errors are thrown as an HRESULT status code.
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/26/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("ParseRequest")
void
ParseRequest(
IN LPCBYTE pbApdu,
IN DWORD cbApdu,
OUT LPBYTE pbCla,
OUT LPBYTE pbIns,
OUT LPBYTE pbP1,
OUT LPBYTE pbP2,
OUT LPCBYTE *ppbData,
OUT LPWORD pwLc,
OUT LPWORD pwLe,
OUT LPDWORD pdwFlags)
{
DWORD dwLen = cbApdu;
DWORD dwFlags = 0;
WORD wLen, wLe, wLc;
//
// Easy stuff.
//
if (4 > dwLen)
throw (HRESULT)E_INVALIDARG;
if (NULL != pbCla)
*pbCla = pbApdu[0];
if (NULL != pbIns)
*pbIns = pbApdu[1];
if (NULL != pbP1)
*pbP1 = pbApdu[2];
if (NULL != pbP2)
*pbP2 = pbApdu[3];
//
// Harder stuff.
//
if (NULL != ppbData)
*ppbData = NULL;
if (4 == dwLen)
{
// Type 1
wLc = 0;
wLe = 0;
}
else if ((0 != pbApdu[4]) || (5 == dwLen))
{
// Short length
wLen = pbApdu[4];
if (5 == dwLen)
{
// Type 2S
wLc = 0;
wLe = wLen;
if (0 == wLen)
dwFlags |= APDU_MAXIMUM_LE;
}
else if (5 == dwLen - wLen)
{
// Type 3S
if (NULL != ppbData)
*ppbData = &pbApdu[5];
wLc = wLen;
wLe = 0;
}
else if (6 == dwLen - wLen)
{
// Type 4S
if (NULL != ppbData)
*ppbData = &pbApdu[5];
wLc = wLen;
wLe = pbApdu[dwLen - 1];
if (0 == wLe)
dwFlags |= APDU_MAXIMUM_LE;
}
else
throw (HRESULT)E_INVALIDARG;
}
else if (7 <= dwLen)
{
// Extended length
dwFlags |= APDU_EXTENDED_LENGTH;
wLen = NetToLocal(&pbApdu[5]);
if (7 == dwLen)
{
// Type 2E
wLe = wLen;
if (0 == wLen)
dwFlags |= APDU_MAXIMUM_LE;
}
else if (7 == dwLen - wLen)
{
// Type 3E
if (NULL != ppbData)
*ppbData = &pbApdu[6];
wLc = wLen;
wLe = 0;
}
else if (9 == dwLen - wLen)
{
// Type 4E
if (NULL != ppbData)
*ppbData = &pbApdu[6];
wLc = wLen;
wLe = NetToLocal(&pbApdu[dwLen - 2]);
if (0 == wLe)
dwFlags |= APDU_MAXIMUM_LE;
}
else
throw (HRESULT)E_INVALIDARG;
}
else
throw (HRESULT)E_INVALIDARG;
if (NULL != pwLc)
*pwLc = wLc;
if (NULL != pwLe)
*pwLe = wLe;
if (NULL != pdwFlags)
*pdwFlags = dwFlags;
}
/*++
ParseReply:
This routine parses an APDU reply.
Arguments:
bfApdu supplies the APDU reply to be parsed.
pbSW1 receives SW1
pbSW2 receives SW2
Return Value:
None
Throws:
Errors are thrown as HRESULT status codes.
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/26/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("ParseReply")
void
ParseReply(
IN CBuffer &bfApdu,
OUT LPBYTE pbSW1,
OUT LPBYTE pbSW2)
{
DWORD dwLen = bfApdu.Length();
if (2 > dwLen)
throw (HRESULT)E_INVALIDARG;
if (NULL != pbSW1)
*pbSW1 = bfApdu[dwLen - 2];
if (NULL != pbSW2)
*pbSW2 = bfApdu[dwLen - 1];
}
/*++
MultiStringToSafeArray:
This function converts a Calais Multistring to a SafeArray Structure.
Arguments:
msz supplies the multistring to be converted.
pprgsz supplies and/or receives the SafeArray.
Return Value:
None
Throws:
Errors are thrown as HRESULT error codes.
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/20/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("MultiStringToSafeArray")
void
MultiStringToSafeArray(
IN LPCTSTR msz,
IN OUT LPSAFEARRAY *pprgsz)
{
LONG ni = 0;
DWORD csz = MStringCount(msz);
VARTYPE vt;
HRESULT hr;
LPCTSTR sz;
CTextString tz;
LPSAFEARRAY pDelArray = NULL;
try
{
if (NULL == *pprgsz)
{
vt = VT_BSTR;
pDelArray = SafeArrayCreateVector(vt, 0, csz);
if (NULL == pDelArray)
throw (HRESULT)E_OUTOFMEMORY;
*pprgsz= pDelArray;
}
else
{
SAFEARRAYBOUND bound;
if (1 != SafeArrayGetDim(*pprgsz))
throw (HRESULT)E_INVALIDARG;
bound.cElements = csz;
bound.lLbound = 0;
hr = SafeArrayRedim(*pprgsz, &bound);
if (FAILED(hr))
throw hr;
hr = SafeArrayGetVartype(*pprgsz, &vt);
if (FAILED(hr))
throw hr;
}
for (sz = FirstString(msz); NULL != sz; sz = NextString(sz))
{
tz = sz;
switch (vt)
{
case VT_LPSTR:
hr = SafeArrayPutElement(*pprgsz, &ni, (LPVOID)((LPCSTR)tz));
break;
case VT_LPWSTR:
hr = SafeArrayPutElement(*pprgsz, &ni, (LPVOID)((LPCWSTR)tz));
break;
case VT_BSTR:
hr = SafeArrayPutElement(*pprgsz, &ni, (LPVOID)((LPCWSTR)tz));
break;
default:
hr = E_INVALIDARG;
}
if (FAILED(hr))
throw hr;
ni += 1;
}
}
catch (...)
{
if (NULL != pDelArray)
{
try { *pprgsz = NULL; } catch (...) {}
SafeArrayDestroy(pDelArray);
throw;
}
}
}
/*++
GuidArrayToSafeArray:
This function converts a vector of GUIDs into its SafeArray form.
Arguments:
pGuids supplies the list of GUIDs
cguids supplies the number of GUIDs in the list
pprgguids supplies a safe array to receive the GUIDs, or if NULL, receives
a new safe array of GUIDs.
Return Value:
None
Throws:
Errors are thrown as HRESULT error codes.
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/25/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("GuidArrayToSafeArray")
void
GuidArrayToSafeArray(
IN LPCGUID pGuids,
IN DWORD cguids,
IN OUT LPSAFEARRAY *pprgguids)
{
LONG ni = 0;
VARTYPE vt;
HRESULT hr;
LPSAFEARRAY pDelArray = NULL;
CTextString tz;
try
{
if (NULL == *pprgguids)
{
vt = VT_CLSID;
pDelArray = SafeArrayCreateVector(vt, 0, cguids);
if (NULL == pDelArray)
throw (HRESULT)E_OUTOFMEMORY;
*pprgguids = pDelArray;
}
else
{
SAFEARRAYBOUND bound;
if (1 != SafeArrayGetDim(*pprgguids))
throw (HRESULT)E_INVALIDARG;
bound.cElements = cguids;
bound.lLbound = 0;
hr = SafeArrayRedim(*pprgguids, &bound);
if (FAILED(hr))
throw hr;
hr = SafeArrayGetVartype(*pprgguids, &vt);
if (FAILED(hr))
throw hr;
}
for (ni = 0; (DWORD)ni < cguids; ni += 1)
{
TCHAR szGuid[40];
StringFromGuid(&pGuids[ni], szGuid);
tz = szGuid;
switch (vt)
{
case VT_LPSTR:
hr = SafeArrayPutElement(
*pprgguids,
&ni,
(LPVOID)((LPCSTR)tz));
break;
case VT_LPWSTR:
hr = SafeArrayPutElement(
*pprgguids,
&ni,
(LPVOID)((LPCWSTR)tz));
break;
case VT_BSTR:
hr = SafeArrayPutElement(
*pprgguids,
&ni,
(LPVOID)((LPCWSTR)tz));
break;
case VT_CLSID:
hr = SafeArrayPutElement(
*pprgguids,
&ni,
(LPVOID)(&pGuids[ni]));
break;
default:
hr = E_INVALIDARG;
}
if (FAILED(hr))
throw hr;
}
}
catch (...)
{
if (NULL != pDelArray)
{
try { *pprgguids = NULL; } catch (...) {}
SafeArrayDestroy(pDelArray);
}
throw;
}
}
/*++
SafeArrayToGuidArray:
This routine converts a given SafeArray object into a list of GUIDs.
Arguments:
prgGuids supplies the SafeArray containing the GUIDs.
bfGuids receives a block of memory containing binary GUIDs.
pcGuids receives the number of GUIDs in the array.
Return Value:
None
Throws:
Errors are thrown as HRESULT status codes.
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/25/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("SafeArrayToGuidArray")
void
SafeArrayToGuidArray(
IN LPSAFEARRAY prgGuids,
OUT CBuffer &bfGuids,
OUT LPDWORD pcGuids)
{
VARTYPE vt;
HRESULT hr;
LONG lLBound, lUBound, lIndex;
LPVOID pVoid;
CTextString tz;
LPGUID pguid;
LONG lOne = 1;
if (1 != SafeArrayGetDim(prgGuids))
throw (HRESULT)E_INVALIDARG;
hr = SafeArrayGetLBound(prgGuids, 1, &lLBound);
if (FAILED(hr))
throw hr;
hr = SafeArrayGetUBound(prgGuids, 1, &lUBound);
if (FAILED(hr))
throw hr;
hr = SafeArrayGetVartype(prgGuids, &vt);
if (FAILED(hr))
throw hr;
lIndex = lUBound - lLBound;
pguid = (LPGUID)bfGuids.Resize(lIndex * sizeof(GUID));
if (NULL != pcGuids)
*pcGuids = (DWORD)lIndex;
for (lIndex = lLBound; lIndex <= lUBound; lIndex += 1)
{
hr = SafeArrayGetElement(prgGuids, &lOne, &pVoid);
if (FAILED(hr))
throw hr;
switch (vt)
{
case VT_LPSTR:
tz = (LPCSTR)pVoid;
if (!GuidFromString(tz, &pguid[lIndex - lLBound]))
hr = E_INVALIDARG;
break;
case VT_LPWSTR:
tz = (LPCWSTR)pVoid;
if (!GuidFromString(tz, &pguid[lIndex - lLBound]))
hr = E_INVALIDARG;
break;
case VT_BSTR:
tz = (BSTR)pVoid;
if (!GuidFromString(tz, &pguid[lIndex - lLBound]))
hr = E_INVALIDARG;
break;
case VT_CLSID:
CopyMemory(&pguid[lIndex - lLBound], pVoid, sizeof(GUID));
break;
default:
hr = E_INVALIDARG;
}
if (FAILED(hr))
throw hr;
}
}
/*++
SafeArrayToMultiString:
This routine converts a SafeArray into a multiString.
Arguments:
prgsz supplies the SafeArray
msz receives the MultiString
Return Value:
None
Throws:
Errors are thrown as HRESULT status codes
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/25/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("SafeArrayToMultiString")
void
SafeArrayToMultiString(
IN LPSAFEARRAY prgsz,
IN OUT CTextMultistring &msz)
{
VARTYPE vt;
HRESULT hr;
LONG lLBound, lUBound, lIndex;
LPVOID pVoid;
CBuffer bf;
if (1 != SafeArrayGetDim(prgsz))
throw (HRESULT)E_INVALIDARG;
hr = SafeArrayGetLBound(prgsz, 1, &lLBound);
if (FAILED(hr))
throw hr;
hr = SafeArrayGetUBound(prgsz, 1, &lUBound);
if (FAILED(hr))
throw hr;
hr = SafeArrayGetVartype(prgsz, &vt);
if (FAILED(hr))
throw hr;
for (lIndex = lLBound; lIndex <= lUBound; lIndex += 1)
{
hr = SafeArrayGetElement(prgsz, &lIndex, &pVoid);
if (FAILED(hr))
throw hr;
switch (vt)
{
case VT_LPSTR:
MStrAdd(bf, (LPCSTR)pVoid);
break;
case VT_LPWSTR:
case VT_BSTR:
MStrAdd(bf, (LPCWSTR)pVoid);
break;
default:
hr = E_INVALIDARG;
}
if (FAILED(hr))
throw hr;
}
msz = (LPCTSTR)bf.Access();
}
/*++
GuidFromString:
This routine converts a string GUID into a binary GUID.
Arguments:
szGuid supplies the GUID in the string format.
pGuid receives the converted GUID.
Return Value:
TRUE - Successful conversion
FALSE - Parsing Error
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/25/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("GuidFromString")
static BOOL
GuidFromString(
LPCTSTR szGuid,
LPGUID pGuid)
{
//
// The following placement assumes Little Endianness.
// 1D92589A-91E4-11d1-93AA-00C04FD91402
// 012345678901234567890123456789012345
// 1 2 3
//
static const BYTE rgbPlace[sizeof(GUID)]
= { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
static const DWORD rgdwPunct[]
= { 8, 13, 18, 23 };
LPCTSTR pch = szGuid;
BYTE bVal;
DWORD dwI, dwJ, dwPunct = 0;
szGuid += _tcsspn(szGuid, TEXT("{[("));
pch = szGuid;
for (dwI = 0; dwI < sizeof(GUID); dwI += 1)
{
if ((BYTE)(pch - szGuid) == rgdwPunct[dwPunct])
{
if (TEXT('-') != *pch)
goto ErrorExit;
dwPunct += 1;
pch += 1;
}
bVal = 0;
for (dwJ = 0; dwJ < 2; dwJ += 1)
{
bVal <<= 4;
if ((TEXT('0') <= *pch) && (TEXT('9') >= *pch))
bVal += *pch - TEXT('0');
else if ((TEXT('A') <= *pch) && (TEXT('F') >= *pch))
bVal += 10 + *pch - TEXT('A');
else if ((TEXT('f') <= *pch) && (TEXT('f') >= *pch))
bVal += 10 + *pch - TEXT('a');
else
goto ErrorExit;
pch += 1;
}
((LPBYTE)pGuid)[rgbPlace[dwI]] = bVal;
}
return TRUE;
ErrorExit:
return FALSE;
}
/*++
ByteBufferToBuffer:
This routine extracts the contents of a ByteBuffer object into a CBuffer
for easy access.
Arguments:
pby supplies the ByteBuffer to be read.
bf receives the contents of pby.
Return Value:
Number of bytes read from the stream.
Throws:
Errors are thrown as HRESULT status codes.
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/29/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("ByteBufferToBuffer")
LONG
ByteBufferToBuffer(
IN LPBYTEBUFFER pby,
OUT CBuffer &bf)
{
HRESULT hr;
LONG nLen = 0;
if (NULL != pby)
{
hr = pby->Seek(0, STREAM_SEEK_END, &nLen);
if (FAILED(hr))
throw hr;
hr = pby->Seek(0, STREAM_SEEK_SET, NULL);
if (FAILED(hr))
throw hr;
hr = pby->Read(
bf.Presize((DWORD)nLen),
nLen,
&nLen);
if (FAILED(hr))
throw hr;
bf.Resize((DWORD)nLen, TRUE);
}
else
bf.Reset();
return nLen;
}
/*++
BufferToByteBuffer:
This routine writes the contents of the supplied CBuffer object into the
supplied IByteBuffer object, replacing any existing contents.
Arguments:
bf supplies the data to be written into pby.
ppby receives the contents of bf.
Return Value:
Number of bytes written to the stream.
Throws:
Errors are thrown as HRESULT status codes.
Remarks:
?Remarks?
Author:
Doug Barlow (dbarlow) 6/29/1999
--*/
#undef __SUBROUTINE__
#define __SUBROUTINE__ TEXT("BufferToByteBuffer")
LONG
BufferToByteBuffer(
IN CBuffer &bf,
OUT LPBYTEBUFFER *ppby)
{
HRESULT hr;
LONG lLen = 0;
if (NULL == *ppby)
{
*ppby = NewByteBuffer();
if (NULL == *ppby)
throw (HRESULT)E_OUTOFMEMORY;
}
hr = (*ppby)->Initialize();
if (FAILED(hr))
throw hr;
hr = (*ppby)->Write(bf.Access(), bf.Length(), &lLen);
if (FAILED(hr))
throw hr;
hr = (*ppby)->Seek(0, STREAM_SEEK_SET, NULL);
if (FAILED(hr))
throw hr;
return lLen;
}