mirror of https://github.com/lianthony/NT4.0
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.
386 lines
12 KiB
386 lines
12 KiB
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dblib.c
|
|
|
|
Abstract:
|
|
|
|
Common api worker routines.
|
|
|
|
Author:
|
|
|
|
Vladimir Z. Vulovic (vladimv) 19 - November - 1993
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "local.h"
|
|
#include "rpldb.h"
|
|
#include "db.h"
|
|
#include "adapter.h"
|
|
#include "boot.h"
|
|
#include "config.h"
|
|
#include "profile.h"
|
|
#include "vendor.h"
|
|
#include "wksta.h"
|
|
#include "dblib.h"
|
|
|
|
|
|
BOOL RplScan(
|
|
IN PRPL_SESSION pSession,
|
|
IN JET_TABLEID TableId,
|
|
IN BOOL FindNextBoot,
|
|
IN OUT PRPL_FILTER pFilter,
|
|
IN OUT PBOOL pTableEnd
|
|
)
|
|
/*++
|
|
Set currency to the next profile or config.
|
|
--*/
|
|
{
|
|
DWORD Error;
|
|
JET_ERR JetError;
|
|
|
|
for ( ; ;) {
|
|
if ( FindNextBoot == TRUE) {
|
|
Error = BootFilterFind( pSession, pFilter, pTableEnd);
|
|
if ( Error != NO_ERROR) {
|
|
return( FALSE);
|
|
}
|
|
if ( *pTableEnd == TRUE) {
|
|
return( TRUE);
|
|
}
|
|
CallB( JetMakeKey( pSession->SesId, TableId, pFilter->BootName, pFilter->BootNameSize, JET_bitNewKey));
|
|
}
|
|
JetError = JetSeek( pSession->SesId, TableId, JET_bitSeekGT);
|
|
if ( JetError != JET_errSuccess) {
|
|
*pTableEnd = TRUE;
|
|
return( TRUE);
|
|
}
|
|
//
|
|
// Verify that current record has the desired boot block & at the
|
|
// same time set index range to be used with JetMove( Next).
|
|
//
|
|
CallB( JetMakeKey( pSession->SesId, TableId, pFilter->BootName, pFilter->BootNameSize, JET_bitNewKey));
|
|
JetError = JetSetIndexRange( pSession->SesId, TableId,
|
|
JET_bitRangeInclusive | JET_bitRangeUpperLimit);
|
|
if ( JetError == JET_errSuccess) {
|
|
return( TRUE);
|
|
}
|
|
//
|
|
// There are no records for current BootName.
|
|
// Get next BootName for VendorId.
|
|
//
|
|
FindNextBoot = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL RplFilterFirst(
|
|
IN PRPL_SESSION pSession,
|
|
IN RPL_TABLE_TAG TableTag,
|
|
IN OUT PRPL_FILTER pFilter OPTIONAL,
|
|
IN LPDWORD pResumeHandle,
|
|
OUT PBOOL pTableEnd
|
|
)
|
|
/*++
|
|
Set currency to the first record for given vendor id, following
|
|
the record described by the resume handle.
|
|
--*/
|
|
{
|
|
#define MAX_RESUME_VALUE_SIZE \
|
|
(RPL_MAX_BOOT_NAME_SIZE + \
|
|
max( RPL_MAX_PROFILE_NAME_SIZE, RPL_MAX_CONFIG_NAME_SIZE))
|
|
#define MAX_NAME_LENGTH \
|
|
(JETBUG_STRING_LENGTH + \
|
|
max( RPL_MAX_PROFILE_NAME_LENGTH, RPL_MAX_CONFIG_NAME_LENGTH))
|
|
BYTE ResumeValue[ MAX_RESUME_VALUE_SIZE];
|
|
DWORD ResumeSize;
|
|
DWORD Error;
|
|
JET_ERR JetError;
|
|
DWORD NameSize;
|
|
WCHAR Name[ MAX_NAME_LENGTH + 1];
|
|
PCHAR Index;
|
|
JET_TABLEID TableId;
|
|
|
|
*pTableEnd = FALSE;
|
|
|
|
switch ( TableTag) {
|
|
case ADAPTER_TABLE_TAG:
|
|
TableId = pSession->AdapterTableId;
|
|
Index = ADAPTER_INDEX_AdapterName;
|
|
break;
|
|
case BOOT_TABLE_TAG:
|
|
TableId = pSession->BootTableId;
|
|
Index = BOOT_INDEX_BootName;
|
|
break;
|
|
case CONFIG_TABLE_TAG:
|
|
TableId = pSession->ConfigTableId;
|
|
Index = pFilter == NULL ? CONFIG_INDEX_ConfigName : CONFIG_INDEX_BootNameConfigName;
|
|
break;
|
|
case PROFILE_TABLE_TAG:
|
|
TableId = pSession->ProfileTableId;
|
|
Index = pFilter == NULL ? PROFILE_INDEX_ProfileName : PROFILE_INDEX_BootNameProfileName;
|
|
break;
|
|
case VENDOR_TABLE_TAG:
|
|
TableId = pSession->VendorTableId;
|
|
Index = VENDOR_INDEX_VendorName;
|
|
break;
|
|
case WKSTA_TABLE_TAG:
|
|
TableId = pSession->WkstaTableId;
|
|
Index = WKSTA_INDEX_WkstaName;
|
|
break;
|
|
default:
|
|
RPL_ASSERT( FALSE);
|
|
}
|
|
|
|
CallB( JetSetCurrentIndex( pSession->SesId, TableId, Index));
|
|
|
|
//
|
|
// The call to move to the beginning of the table is not redundant.
|
|
// E.g. JET_errNoCurrentRecord will be returned in case of empty table.
|
|
//
|
|
JetError = JetMove( pSession->SesId, TableId, JET_MoveFirst, 0);
|
|
if ( JetError < 0) {
|
|
if ( JetError == JET_errNoCurrentRecord) {
|
|
*pTableEnd = TRUE;
|
|
return( TRUE);
|
|
} else {
|
|
RplDump( ++RG_Assert, ("JetError=%d", JetError));
|
|
return( FALSE);
|
|
}
|
|
}
|
|
|
|
if ( (ARGUMENT_PRESENT( pResumeHandle)) && *pResumeHandle != 0) {
|
|
ResumeSize = sizeof( ResumeValue);
|
|
if ( !ResumeKeyGet( pSession, *pResumeHandle, ResumeValue, &ResumeSize)) {
|
|
return( FALSE);
|
|
}
|
|
if ( pFilter == NULL) {
|
|
CallB( JetMakeKey( pSession->SesId, TableId, ResumeValue, ResumeSize, JET_bitNewKey));
|
|
CallB( JetSeek( pSession->SesId, TableId, JET_bitSeekGT));
|
|
return( TRUE);
|
|
}
|
|
pFilter->BootNameSize = (wcslen( (PWCHAR)ResumeValue) + 1) * sizeof(WCHAR);
|
|
memcpy( pFilter->BootName, ResumeValue, pFilter->BootNameSize);
|
|
NameSize = (wcslen( (PWCHAR)(ResumeValue + pFilter->BootNameSize)) + 1)
|
|
* sizeof(WCHAR);
|
|
memcpy( Name, ResumeValue + pFilter->BootNameSize, NameSize);
|
|
RPL_ASSERT( ResumeSize == pFilter->BootNameSize + NameSize);
|
|
} else {
|
|
if ( pFilter == NULL) {
|
|
return( TRUE);
|
|
}
|
|
pFilter->BootNameSize = 0; // scan from the beginning
|
|
Error = BootFilterFind( pSession, pFilter, pTableEnd);
|
|
if ( Error != NO_ERROR) {
|
|
return( FALSE);
|
|
}
|
|
if ( *pTableEnd == TRUE) {
|
|
return( TRUE);
|
|
}
|
|
NameSize = 0;
|
|
}
|
|
CallB( JetMakeKey( pSession->SesId, TableId, pFilter->BootName, pFilter->BootNameSize, JET_bitNewKey));
|
|
if ( NameSize != 0) {
|
|
#ifdef RPL_JETBUG
|
|
memcpy( (PBYTE)Name + NameSize, JETBUG_STRING, JETBUG_STRING_SIZE);
|
|
NameSize += JETBUG_STRING_LENGTH * sizeof(WCHAR);
|
|
#endif
|
|
CallB( JetMakeKey( pSession->SesId, TableId, Name, NameSize, 0));
|
|
}
|
|
return( RplScan( pSession, TableId, FALSE, pFilter, pTableEnd));
|
|
}
|
|
|
|
|
|
VOID RplFilterSave(
|
|
IN PRPL_SESSION pSession,
|
|
IN DWORD ServerHandle,
|
|
IN PRPL_FILTER pFilter,
|
|
IN PWCHAR Name,
|
|
IN PDWORD pResumeHandle
|
|
)
|
|
{
|
|
BYTE ResumeBuffer[ 30 * sizeof(WCHAR)]; // BUGBUG hardcoding
|
|
DWORD ResumeSize;
|
|
DWORD NameSize;
|
|
if ( pFilter != NULL) {
|
|
ResumeSize = pFilter->BootNameSize;
|
|
memcpy( ResumeBuffer, pFilter->BootName, ResumeSize);
|
|
} else {
|
|
ResumeSize = 0;
|
|
}
|
|
NameSize = ( wcslen( Name) + 1) * sizeof(WCHAR);
|
|
memcpy( ResumeBuffer + ResumeSize, Name, NameSize);
|
|
ResumeSize += NameSize;
|
|
(VOID)ResumeKeySet( pSession, ServerHandle, ResumeBuffer, ResumeSize, pResumeHandle);
|
|
}
|
|
|
|
|
|
BOOL RplFilterNext(
|
|
IN PRPL_SESSION pSession,
|
|
IN JET_TABLEID TableId,
|
|
IN OUT PRPL_FILTER pFilter,
|
|
OUT PBOOL pTableEnd
|
|
)
|
|
{
|
|
JET_ERR JetError;
|
|
|
|
JetError = JetMove( pSession->SesId, TableId, JET_MoveNext, 0);
|
|
if ( JetError == JET_errSuccess) {
|
|
return( TRUE);
|
|
}
|
|
if ( pFilter == NULL) {
|
|
RplDump( RG_DebugLevel & RPL_DEBUG_DB, (
|
|
"FilterNext: TableId=0x%x, JetError=%d", TableId, JetError));
|
|
*pTableEnd = TRUE;
|
|
return( TRUE); // assume end of table
|
|
} else {
|
|
RplDump( RG_DebugLevel & RPL_DEBUG_DB, (
|
|
"FilterNext: TableId=0x%x, BootName=%ws, JetError=%d",
|
|
TableId, pFilter->BootName, JetError));
|
|
return( RplScan( pSession, TableId, TRUE, pFilter, pTableEnd));
|
|
}
|
|
}
|
|
|
|
|
|
BOOL RplFind(
|
|
IN PRPL_SESSION pSession,
|
|
IN RPL_TABLE_TAG TableTag,
|
|
IN PWCHAR Name
|
|
)
|
|
{
|
|
JET_ERR JetError;
|
|
PCHAR Index;
|
|
JET_TABLEID TableId;
|
|
|
|
switch ( TableTag) {
|
|
case ADAPTER_TABLE_TAG:
|
|
TableId = pSession->AdapterTableId;
|
|
Index = ADAPTER_INDEX_AdapterName;
|
|
break;
|
|
case CONFIG_TABLE_TAG:
|
|
TableId = pSession->ConfigTableId;
|
|
Index = CONFIG_INDEX_ConfigName;
|
|
break;
|
|
case PROFILE_TABLE_TAG:
|
|
TableId = pSession->ProfileTableId;
|
|
Index = PROFILE_INDEX_ProfileName;
|
|
break;
|
|
case VENDOR_TABLE_TAG:
|
|
TableId = pSession->VendorTableId;
|
|
Index = VENDOR_INDEX_VendorName;
|
|
break;
|
|
case WKSTA_TABLE_TAG:
|
|
TableId = pSession->WkstaTableId;
|
|
Index = WKSTA_INDEX_WkstaName;
|
|
break;
|
|
default:
|
|
RPL_RETURN( FALSE);
|
|
}
|
|
CallB( JetSetCurrentIndex( pSession->SesId, TableId, Index));
|
|
CallB( JetMakeKey( pSession->SesId, TableId, Name, ( wcslen( Name) + 1) * sizeof(WCHAR), JET_bitNewKey));
|
|
JetError = JetSeek( pSession->SesId, TableId, JET_bitSeekEQ);
|
|
if ( JetError < 0) {
|
|
#ifdef RPL_DEBUG
|
|
//
|
|
// JET_errNoCurrentRecord will be returned in case of empty table.
|
|
//
|
|
if ( JetError != JET_errRecordNotFound
|
|
&& JetError != JET_errNoCurrentRecord) {
|
|
RplDump( ++RG_Assert, ("JetError=%d", JetError));
|
|
}
|
|
#endif
|
|
return( FALSE);
|
|
}
|
|
return( TRUE);
|
|
}
|
|
|
|
|
|
BOOL RplFindByField(
|
|
IN PRPL_SESSION pSession,
|
|
IN RPL_TABLE_TAG TableTag,
|
|
IN PCHAR IndexName,
|
|
IN PWCHAR FieldName
|
|
)
|
|
/*++
|
|
Returns TRUE if it can find a record (the first record) that has
|
|
FieldName as a value. Returns FALSE otherwise.
|
|
|
|
We cannot use SetIndexRange technique here because FieldName is only
|
|
the first part of an index & we would never find a match.
|
|
--*/
|
|
{
|
|
DWORD FieldNameSize;
|
|
JET_ERR JetError;
|
|
BYTE Data[ 300];
|
|
DWORD DataSize;
|
|
JET_TABLEID TableId;
|
|
JET_COLUMNID ColumnId;
|
|
|
|
switch ( TableTag) {
|
|
case CONFIG_TABLE_TAG:
|
|
TableId = pSession->ConfigTableId;
|
|
if ( strcmp( IndexName, CONFIG_INDEX_BootNameConfigName) == 0) {
|
|
ColumnId = ProfileTable[ CONFIG_BootName].ColumnId;
|
|
} else {
|
|
RPL_RETURN( FALSE);
|
|
}
|
|
break;
|
|
case PROFILE_TABLE_TAG:
|
|
TableId = pSession->ProfileTableId;
|
|
if ( strcmp( IndexName, PROFILE_INDEX_ConfigNameProfileName) == 0) {
|
|
ColumnId = ProfileTable[ PROFILE_ConfigName].ColumnId;
|
|
} else if ( strcmp( IndexName, PROFILE_INDEX_BootNameProfileName) == 0) {
|
|
ColumnId = ProfileTable[ PROFILE_BootName].ColumnId;
|
|
} else {
|
|
RPL_RETURN( FALSE);
|
|
}
|
|
break;
|
|
case WKSTA_TABLE_TAG:
|
|
TableId = pSession->WkstaTableId;
|
|
if ( strcmp( IndexName, WKSTA_INDEX_ProfileNameWkstaName) == 0) {
|
|
ColumnId = WkstaTable[ WKSTA_ProfileName].ColumnId;
|
|
} else if ( strcmp( IndexName, WKSTA_INDEX_BootNameWkstaName) == 0) {
|
|
ColumnId = WkstaTable[ WKSTA_BootName].ColumnId;
|
|
} else {
|
|
RPL_RETURN( FALSE);
|
|
}
|
|
break;
|
|
default:
|
|
RPL_RETURN( FALSE);
|
|
}
|
|
|
|
CallB( JetSetCurrentIndex( pSession->SesId, TableId, IndexName));
|
|
FieldNameSize = ( wcslen( FieldName) + 1) * sizeof(WCHAR);
|
|
CallB( JetMakeKey( pSession->SesId, TableId, FieldName, FieldNameSize, JET_bitNewKey));
|
|
JetError = JetSeek( pSession->SesId, TableId, JET_bitSeekGE);
|
|
if ( JetError < 0) {
|
|
return( FALSE);
|
|
}
|
|
CallB( JetRetrieveColumn( pSession->SesId, TableId, ColumnId, Data,
|
|
sizeof( Data), &DataSize, 0, NULL));
|
|
if ( FieldNameSize != DataSize) {
|
|
return( FALSE);
|
|
}
|
|
if ( memcmp( FieldName, Data, DataSize) != 0) {
|
|
return( FALSE);
|
|
}
|
|
return( TRUE); // we found record using this field
|
|
}
|
|
|
|
|
|
DWORD AdapterNameToVendorId( IN PWCHAR AdapterName)
|
|
{
|
|
WCHAR VendorName[ RPL_VENDOR_NAME_LENGTH + 1];
|
|
//
|
|
// Yes, we could zero the char in AdapterName, calculate VendorId,
|
|
// then restore char. But this is more robust though.
|
|
//
|
|
memcpy( VendorName, AdapterName, RPL_VENDOR_NAME_LENGTH*sizeof(WCHAR));
|
|
VendorName[ RPL_VENDOR_NAME_LENGTH] = 0;
|
|
return( wcstoul( VendorName, NULL, 16));
|
|
}
|