windows-nt/Source/XPSP1/NT/ds/nw/nwlib/win95/nds32w95.c
2020-09-26 16:20:57 +08:00

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);
}