412 lines
10 KiB
C
412 lines
10 KiB
C
/*++
|
|
|
|
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;
|
|
}
|