/*++ 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 #ifdef WIN95 #include #include #include 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); }