windows-nt/Source/XPSP1/NT/ds/netapi/svcdlls/srvsvc/client/csc.c

412 lines
10 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1991-1992 Microsoft Corporation
Module Name:
csc.c
Abstract:
These are the server service API RPC client stubs for CSC
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <rpcutil.h>
#include <lmcons.h>
#include <lmerr.h>
#include <lmapibuf.h>
#include <lmshare.h>
#include "cscp.h"
static FARPROC pCSCFindFirstFile = NULL;
static FARPROC pCSCFindNextFile = NULL;
static FARPROC pCSCFindClose = NULL;
static FARPROC pCSCIsServerOffline = NULL;
//
// Load the cscdll.dll library, and pull out the functions that we need.
//
GetCSCEntryPoints()
{
HANDLE hMod;
if( pCSCFindFirstFile == NULL ) {
//
// Get the entry points in reverse order for multithread protection
//
hMod = LoadLibrary(L"cscdll.dll");
if( hMod == NULL ) {
return 0;
}
pCSCFindClose = GetProcAddress(hMod,"CSCFindClose");
if( pCSCFindClose == NULL ) {
return 0;
}
pCSCFindNextFile = GetProcAddress(hMod,"CSCFindNextFileW" );
if( pCSCFindNextFile == NULL ) {
return 0;
}
pCSCIsServerOffline = GetProcAddress(hMod, "CSCIsServerOfflineW" );
if( pCSCIsServerOffline == NULL ) {
return 0;
}
pCSCFindFirstFile = GetProcAddress(hMod,"CSCFindFirstFileW" );
}
return pCSCFindFirstFile != 0;
}
//
// return TRUE if we think this server is in the offline state
//
BOOLEAN
CSCIsServerOffline(
IN LPWSTR servername
)
{
BOOL isOffline;
if( GetCSCEntryPoints() &&
pCSCIsServerOffline( servername, &isOffline ) &&
isOffline == TRUE ) {
return TRUE;
}
return FALSE;
}
//
// Emulate NetShareEnum() for offline servers
//
NET_API_STATUS NET_API_FUNCTION
CSCNetShareEnum (
IN LPWSTR servername,
IN DWORD level,
OUT LPBYTE *bufptr,
OUT LPDWORD entriesread,
OUT LPDWORD totalentries
)
{
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAW sFind32;
DWORD dwError, dwStatus, dwPinCount, dwHintFlags;
FILETIME ftOrgTime;
NET_API_STATUS apiStatus;
LPWSTR server, share;
PBYTE outbuf = NULL, endp;
DWORD count, numFound, sharelen;
if( (level != 0 && level != 1) ) {
return ERROR_INVALID_PARAMETER;
}
try {
if (servername[0] != L'\\')
{
// OK
}
else if ((servername[0] == L'\\') && (servername[1] == L'\\'))
{
servername += 2;
}
else{
apiStatus = ERROR_NOT_SUPPORTED;
goto try_exit;
}
count = 1024;
retry:
numFound = 0;
//
// Allocate space for the results
//
if( outbuf != NULL ) {
NetApiBufferFree( outbuf );
outbuf = NULL;
count *= 2;
}
apiStatus = NetApiBufferAllocate( count, &outbuf );
if( apiStatus != NO_ERROR ) {
goto try_exit;
}
endp = outbuf + count;
RtlZeroMemory( outbuf, count );
//
// See if we can enumerate the cached servers and shares
//
if( hFind != INVALID_HANDLE_VALUE ) {
pCSCFindClose( hFind );
hFind = INVALID_HANDLE_VALUE;
}
hFind = (HANDLE)pCSCFindFirstFile( NULL,
&sFind32,
&dwStatus,
&dwPinCount,
&dwHintFlags,
&ftOrgTime
);
if( hFind == INVALID_HANDLE_VALUE ) {
NetApiBufferFree( outbuf );
apiStatus = ERROR_NOT_SUPPORTED;
goto try_exit;
}
do {
//
// For each entry, take a look to see if it's one that we want. If
// it is one, pack the results into the output buffer. If the output
// buffer is too small, grow the buffer and start over again.
//
//
// The name returned should be \\server\sharename
//
if( sFind32.cFileName[0] != L'\\' || sFind32.cFileName[1] != L'\\' ||
sFind32.cFileName[2] == L'\0' ) {
//
// We got a strange server name entry
//
continue;
}
server = &sFind32.cFileName[2];
for( share = server; *share && *share != '\\'; share++ );
if( share[0] != '\\' ) {
//
// No share component?
//
continue;
}
//
// NULL terminate the servername
//
*share++ = L'\0';
if( lstrcmpiW( servername, server ) ) {
continue;
}
//
// We've found an entry for this server!
//
for( sharelen = 0; share[sharelen]; sharelen++ ) {
if( share[ sharelen ] == L'\\' )
break;
}
if( sharelen == 0 ) {
//
// No share component?
//
continue;
}
sharelen *= sizeof( WCHAR ); // it's UNICODE
sharelen += sizeof( WCHAR ); // the NULL
if( level == 0 ) {
PSHARE_INFO_0 s0 = (PSHARE_INFO_0)outbuf + numFound;;
if( (PBYTE)(endp - sharelen) < (PBYTE)(s0 + sizeof( s0 )) ) {
goto retry;
}
endp -= sharelen;
RtlCopyMemory( endp, share, sharelen );
s0->shi0_netname = (LPWSTR)endp;
} else {
PSHARE_INFO_1 s1 = (PSHARE_INFO_1)outbuf + numFound;
if( (PBYTE)(endp - sharelen) < (PBYTE)(s1 + sizeof( s1 )) ) {
goto retry;
}
endp -= sharelen;
RtlCopyMemory( endp, share, sharelen );
s1->shi1_netname = (LPWSTR)endp;
s1->shi1_type = STYPE_DISKTREE;
s1->shi1_remark = (LPWSTR)(endp + sharelen - sizeof(WCHAR));
}
numFound++;
} while( pCSCFindNextFile(hFind, &sFind32, &dwStatus, &dwPinCount, &dwHintFlags, &ftOrgTime) );
pCSCFindClose(hFind);
apiStatus = NERR_Success;
if( numFound == 0 ) {
NetApiBufferFree( outbuf );
outbuf = NULL;
}
*bufptr = outbuf;
*entriesread = numFound;
*totalentries = numFound;
try_exit:;
} except( EXCEPTION_EXECUTE_HANDLER ) {
if( outbuf ) {
NetApiBufferFree( outbuf );
}
if( hFind != INVALID_HANDLE_VALUE ) {
pCSCFindClose( hFind );
}
apiStatus = ERROR_INVALID_PARAMETER;
}
return apiStatus;
}
//
// Emulate NetShareGetInfo() for an offline server
//
NET_API_STATUS NET_API_FUNCTION
CSCNetShareGetInfo (
IN LPTSTR servername,
IN LPTSTR netname,
IN DWORD level,
OUT LPBYTE *bufptr
)
{
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAW sFind32;
DWORD dwError, dwStatus, dwPinCount, dwHintFlags;
FILETIME ftOrgTime;
NET_API_STATUS apiStatus = ERROR_NOT_SUPPORTED;
LPWSTR server, share;
DWORD netNameSize;
if( (level != 0 && level != 1) ) {
return ERROR_NOT_SUPPORTED;
}
try {
hFind = (HANDLE)pCSCFindFirstFile( NULL,
&sFind32,
&dwStatus,
&dwPinCount,
&dwHintFlags,
&ftOrgTime
);
if( hFind == INVALID_HANDLE_VALUE ) {
goto try_exit;
}
//
// Loop through the entries until we find one we want
//
do {
server = &sFind32.cFileName[0];
for( share = server; *share && *share != '\\'; share++ );
if( share[0] != '\\' ) {
//
// No share component?
//
continue;
}
//
// NULL terminate the servername
//
*share++ = L'\0';
if( lstrcmpiW( servername, server ) || lstrcmpiW( share, netname ) ) {
continue;
}
for( netNameSize = 0; netname[ netNameSize ]; netNameSize++ )
;
netNameSize += 1;
netNameSize *= sizeof( WCHAR );
//
// Got the match!
//
if( level == 0 ) {
PSHARE_INFO_0 s0;
apiStatus = NetApiBufferAllocate( sizeof(*s0) + netNameSize, &s0 );
if( apiStatus == NO_ERROR ) {
s0->shi0_netname = (LPTSTR)(s0 + 1);
RtlCopyMemory( s0->shi0_netname, netname, netNameSize );
*bufptr = (LPBYTE)s0;
apiStatus = NERR_Success;
}
} else {
PSHARE_INFO_1 s1;
apiStatus = NetApiBufferAllocate( sizeof(*s1) + netNameSize, &s1 );
if( apiStatus == NO_ERROR ) {
s1->shi1_netname = (LPTSTR)(s1 + 1);
RtlCopyMemory( s1->shi1_netname, netname, netNameSize );
s1->shi1_type = STYPE_DISKTREE;
s1->shi1_remark = s1->shi1_netname + netNameSize/sizeof(WCHAR) - sizeof(WCHAR);
*bufptr = (LPBYTE)s1;
apiStatus = NERR_Success;
}
}
break;
} while( pCSCFindNextFile(hFind,&sFind32,&dwStatus,&dwPinCount,&dwHintFlags, &ftOrgTime) );
pCSCFindClose( hFind );
try_exit:;
} except ( EXCEPTION_EXECUTE_HANDLER ) {
if( hFind != INVALID_HANDLE_VALUE ) {
pCSCFindClose( hFind );
}
apiStatus = ERROR_INVALID_PARAMETER;
}
return apiStatus;
}