303 lines
9.2 KiB
C
303 lines
9.2 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1995 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
Nds32W95.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This module implements functions to Read, Add, Modify, and Remove
|
||
|
NDS Objects and Attributes using the Microsoft Netware redirector.
|
||
|
All functions in this file are NT specific.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Glenn Curtis [GlennC] 04-Jan-1996
|
||
|
Glenn Curtis [GlennC] 24-Apr-1996 - Added schema APIs
|
||
|
Glenn Curtis [GlennC] 20-Jun-1996 - Added search API
|
||
|
Felix Wong [t-felixw] 24-Sep-1996 - Added Win95 Support
|
||
|
--*/
|
||
|
|
||
|
#include <procs.h>
|
||
|
|
||
|
#ifdef WIN95
|
||
|
#include <msnwapi.h>
|
||
|
#include <utils95.h>
|
||
|
#include <nw95.h>
|
||
|
char ROOT_STR[] = "[Root]";
|
||
|
#endif
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
DWORD Signature;
|
||
|
HANDLE NdsTree;
|
||
|
DWORD ObjectId;
|
||
|
DWORD ResumeId;
|
||
|
DWORD NdsRawDataBuffer;
|
||
|
DWORD NdsRawDataSize;
|
||
|
DWORD NdsRawDataId;
|
||
|
DWORD NdsRawDataCount;
|
||
|
WCHAR Name[1];
|
||
|
|
||
|
} NDS_OBJECT, * LPNDS_OBJECT;
|
||
|
|
||
|
//
|
||
|
// Flags used for the function ParseNdsUncPath()
|
||
|
//
|
||
|
#define PARSE_NDS_GET_TREE_NAME 0
|
||
|
#define PARSE_NDS_GET_PATH_NAME 1
|
||
|
#define PARSE_NDS_GET_OBJECT_NAME 2
|
||
|
|
||
|
|
||
|
WORD
|
||
|
ParseNdsUncPath( IN OUT LPWSTR * Result,
|
||
|
IN LPWSTR ObjectPathName,
|
||
|
IN DWORD flag );
|
||
|
|
||
|
DWORD
|
||
|
GetFirstNdsSubTreeEntry(
|
||
|
OUT LPNDS_OBJECT lpNdsObject,
|
||
|
IN DWORD BufferSize )
|
||
|
{
|
||
|
UNICODE_STRING UName;
|
||
|
LPSTR szName;
|
||
|
struct _nds_tag *pBufTag;
|
||
|
PBYTE LocalBuffer;
|
||
|
UINT nObjects;
|
||
|
DWORD* pBuffer;
|
||
|
NW_STATUS nwstatus;
|
||
|
NTSTATUS ntstatus = STATUS_UNSUCCESSFUL;
|
||
|
lpNdsObject->NdsRawDataSize = BufferSize;
|
||
|
//
|
||
|
// Determine size of NDS raw data buffer to use. Set to at least 8KB.
|
||
|
//
|
||
|
if ( lpNdsObject->NdsRawDataSize < 8192 )
|
||
|
lpNdsObject->NdsRawDataSize = 8192;
|
||
|
|
||
|
//
|
||
|
// Create NDS raw data buffer.
|
||
|
//
|
||
|
lpNdsObject->NdsRawDataBuffer = (DWORD) LocalAlloc( LMEM_ZEROINIT,
|
||
|
lpNdsObject->NdsRawDataSize );
|
||
|
LocalBuffer = (PBYTE)LocalAlloc( LMEM_ZEROINIT,lpNdsObject->NdsRawDataSize );
|
||
|
|
||
|
if ( lpNdsObject->NdsRawDataBuffer == 0 || LocalBuffer == 0)
|
||
|
{
|
||
|
KdPrint(("NWWORKSTATION: NwGetFirstNdsSubTreeEntry LocalAlloc Failed %lu\n", GetLastError()));
|
||
|
ntstatus = STATUS_NO_MEMORY;
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set up to get initial NDS subordinate list.
|
||
|
//
|
||
|
lpNdsObject->NdsRawDataId = INITIAL_ITERATION;
|
||
|
|
||
|
RtlInitUnicodeString( &UName, lpNdsObject->Name );
|
||
|
|
||
|
UName.Length = ParseNdsUncPath( (LPWSTR *) &UName.Buffer,
|
||
|
lpNdsObject->Name,
|
||
|
PARSE_NDS_GET_PATH_NAME );
|
||
|
|
||
|
if ( UName.Length == 0 )
|
||
|
{
|
||
|
szName = (LPSTR)LocalAlloc( LPTR, sizeof(char) * (strlen(ROOT_STR) + 1));
|
||
|
if (szName == NULL) {
|
||
|
ntstatus = STATUS_NO_MEMORY;
|
||
|
goto Exit;
|
||
|
};
|
||
|
strcpy(szName,ROOT_STR);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szName = AllocateAnsiString(UName.Buffer);
|
||
|
if (szName == NULL) {
|
||
|
ntstatus = STATUS_NO_MEMORY;
|
||
|
goto Exit;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
nwstatus = NDSListSubordinates(
|
||
|
szName,
|
||
|
LocalBuffer,
|
||
|
lpNdsObject->NdsRawDataSize,
|
||
|
&lpNdsObject->NdsRawDataId,
|
||
|
&nObjects
|
||
|
);
|
||
|
ntstatus = MapNwToNtStatus(nwstatus);
|
||
|
|
||
|
if ( ntstatus == STATUS_SUCCESS) {
|
||
|
pBufTag = (struct _nds_tag *)LocalBuffer;
|
||
|
pBuffer = (DWORD*)lpNdsObject->NdsRawDataBuffer;
|
||
|
*pBuffer++ = (DWORD)ntstatus;
|
||
|
*pBuffer++ = (DWORD)lpNdsObject->NdsRawDataId;
|
||
|
*pBuffer++ = (DWORD)nObjects;
|
||
|
memcpy( (LPBYTE)pBuffer,
|
||
|
(char *)pBufTag->nextItem,
|
||
|
pBufTag->bufEnd - (char *)pBufTag->nextItem);
|
||
|
if (((PNDS_RESPONSE_SUBORDINATE_LIST)
|
||
|
lpNdsObject->NdsRawDataBuffer)->SubordinateEntries != 0 ) {
|
||
|
lpNdsObject->NdsRawDataCount = ((PNDS_RESPONSE_SUBORDINATE_LIST)
|
||
|
lpNdsObject->NdsRawDataBuffer)->SubordinateEntries - 1;
|
||
|
|
||
|
lpNdsObject->ResumeId = lpNdsObject->NdsRawDataBuffer +
|
||
|
sizeof(NDS_RESPONSE_SUBORDINATE_LIST);
|
||
|
// Successful exit
|
||
|
goto Exit;
|
||
|
}
|
||
|
}
|
||
|
// No entries
|
||
|
lpNdsObject->NdsRawDataBuffer = 0;
|
||
|
lpNdsObject->NdsRawDataSize = 0;
|
||
|
lpNdsObject->NdsRawDataId = INITIAL_ITERATION;
|
||
|
lpNdsObject->NdsRawDataCount = 0;
|
||
|
lpNdsObject->ResumeId = 0;
|
||
|
ntstatus = STATUS_NO_MORE_ENTRIES;
|
||
|
Exit:
|
||
|
if (szName)
|
||
|
LocalFree(szName);
|
||
|
if (LocalBuffer)
|
||
|
LocalFree(LocalBuffer);
|
||
|
if (ntstatus != STATUS_SUCCESS) {
|
||
|
if ( lpNdsObject->NdsRawDataBuffer )
|
||
|
(void) LocalFree( (HLOCAL) lpNdsObject->NdsRawDataBuffer );
|
||
|
}
|
||
|
|
||
|
return RtlNtStatusToDosError(ntstatus);
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
GetNextNdsSubTreeEntry(
|
||
|
OUT LPNDS_OBJECT lpNdsObject )
|
||
|
{
|
||
|
NTSTATUS nwstatus;
|
||
|
NTSTATUS ntstatus = STATUS_SUCCESS;
|
||
|
struct _nds_tag *pBufTag;
|
||
|
PBYTE pbRaw;
|
||
|
DWORD dwStrLen;
|
||
|
LPSTR szName;
|
||
|
UINT nObjects;
|
||
|
DWORD *pBuffer;
|
||
|
|
||
|
if ( lpNdsObject->NdsRawDataCount == 0 &&
|
||
|
lpNdsObject->NdsRawDataId == INITIAL_ITERATION )
|
||
|
return WN_NO_MORE_ENTRIES;
|
||
|
|
||
|
if ( lpNdsObject->NdsRawDataCount == 0 &&
|
||
|
lpNdsObject->NdsRawDataId != INITIAL_ITERATION )
|
||
|
{
|
||
|
PBYTE LocalBuffer;
|
||
|
UNICODE_STRING UName;
|
||
|
|
||
|
LocalBuffer = (PBYTE) LocalAlloc( LMEM_ZEROINIT,lpNdsObject->NdsRawDataSize );
|
||
|
if ( lpNdsObject->NdsRawDataBuffer == 0 || LocalBuffer == 0)
|
||
|
{
|
||
|
KdPrint(("NWWORKSTATION: NwGetFirstNdsSubTreeEntry LocalAlloc Failed %lu\n", GetLastError()));
|
||
|
ntstatus = STATUS_NO_MEMORY;
|
||
|
goto Exit;
|
||
|
}
|
||
|
|
||
|
RtlInitUnicodeString( &UName, lpNdsObject->Name );
|
||
|
|
||
|
UName.Length = ParseNdsUncPath( (LPWSTR *) &UName.Buffer,
|
||
|
lpNdsObject->Name,
|
||
|
PARSE_NDS_GET_PATH_NAME );
|
||
|
|
||
|
if ( UName.Length == 0 )
|
||
|
{
|
||
|
szName = (LPSTR)LocalAlloc( LPTR, sizeof(char) * (strlen(ROOT_STR) + 1));
|
||
|
if (szName == NULL) {
|
||
|
ntstatus = STATUS_NO_MEMORY;
|
||
|
goto Exit;
|
||
|
};
|
||
|
strcpy(szName,ROOT_STR);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szName = AllocateAnsiString(UName.Buffer);
|
||
|
if (szName == NULL) {
|
||
|
ntstatus = STATUS_NO_MEMORY;
|
||
|
goto Exit;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
nwstatus = NDSListSubordinates(
|
||
|
szName,
|
||
|
(LPBYTE)LocalBuffer,
|
||
|
lpNdsObject->NdsRawDataSize,
|
||
|
&lpNdsObject->NdsRawDataId,
|
||
|
&nObjects
|
||
|
);
|
||
|
ntstatus = MapNwToNtStatus(nwstatus);
|
||
|
|
||
|
if (ntstatus == STATUS_SUCCESS) {
|
||
|
pBufTag = (struct _nds_tag *)LocalBuffer;
|
||
|
pBuffer = (DWORD*)lpNdsObject->NdsRawDataBuffer;
|
||
|
*pBuffer++ = (DWORD)ntstatus;
|
||
|
*pBuffer++ = (DWORD)lpNdsObject->NdsRawDataId;
|
||
|
*pBuffer++ = (DWORD)nObjects;
|
||
|
memcpy( (LPBYTE)pBuffer,
|
||
|
(char *)pBufTag->nextItem,
|
||
|
pBufTag->bufEnd - (char *)pBufTag->nextItem);
|
||
|
lpNdsObject->NdsRawDataCount = ((PNDS_RESPONSE_SUBORDINATE_LIST)
|
||
|
lpNdsObject->NdsRawDataBuffer)->SubordinateEntries - 1;
|
||
|
|
||
|
lpNdsObject->ResumeId = lpNdsObject->NdsRawDataBuffer +
|
||
|
sizeof(NDS_RESPONSE_SUBORDINATE_LIST);
|
||
|
}
|
||
|
Exit:
|
||
|
if (LocalBuffer)
|
||
|
LocalFree(LocalBuffer);
|
||
|
if (szName)
|
||
|
LocalFree(szName);
|
||
|
if (ntstatus != STATUS_SUCCESS)
|
||
|
{
|
||
|
if ( lpNdsObject->NdsRawDataBuffer )
|
||
|
(void) LocalFree( (HLOCAL) lpNdsObject->NdsRawDataBuffer );
|
||
|
lpNdsObject->NdsRawDataBuffer = 0;
|
||
|
lpNdsObject->NdsRawDataSize = 0;
|
||
|
lpNdsObject->NdsRawDataId = INITIAL_ITERATION;
|
||
|
lpNdsObject->NdsRawDataCount = 0;
|
||
|
return WN_NO_MORE_ENTRIES;
|
||
|
}
|
||
|
return RtlNtStatusToDosError(ntstatus);
|
||
|
}
|
||
|
|
||
|
lpNdsObject->NdsRawDataCount--;
|
||
|
|
||
|
//
|
||
|
// Move pointer past the fixed header portion of a
|
||
|
// NDS_RESPONSE_SUBORDINATE_ENTRY
|
||
|
//
|
||
|
pbRaw = (BYTE *) lpNdsObject->ResumeId;
|
||
|
pbRaw += sizeof(NDS_RESPONSE_SUBORDINATE_ENTRY);
|
||
|
|
||
|
//
|
||
|
// Move pointer past the length value of the Class Name string
|
||
|
// of a NDS_RESPONSE_SUBORDINATE_ENTRY
|
||
|
//
|
||
|
dwStrLen = * (DWORD *) pbRaw;
|
||
|
pbRaw += sizeof(DWORD);
|
||
|
|
||
|
//
|
||
|
// Move pointer past the Class Name string of a
|
||
|
// NDS_RESPONSE_SUBORDINATE_ENTRY
|
||
|
//
|
||
|
pbRaw += ROUNDUP4( dwStrLen );
|
||
|
|
||
|
//
|
||
|
// Move pointer past the length value of the Object Name string
|
||
|
// of a NDS_RESPONSE_SUBORDINATE_ENTRY
|
||
|
//
|
||
|
dwStrLen = * (DWORD *) pbRaw;
|
||
|
pbRaw += sizeof(DWORD);
|
||
|
|
||
|
lpNdsObject->ResumeId = (DWORD) ( pbRaw + ROUNDUP4( dwStrLen ) );
|
||
|
|
||
|
return RtlNtStatusToDosError(ntstatus);
|
||
|
}
|
||
|
|