Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

411 lines
11 KiB

  1. /*++
  2. Copyright (c) 1991-1992 Microsoft Corporation
  3. Module Name:
  4. csc.c
  5. Abstract:
  6. These are the server service API RPC client stubs for CSC
  7. --*/
  8. #include <nt.h>
  9. #include <ntrtl.h>
  10. #include <nturtl.h>
  11. #include <windows.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <time.h>
  16. #include <rpcutil.h>
  17. #include <lmcons.h>
  18. #include <lmerr.h>
  19. #include <lmapibuf.h>
  20. #include <lmshare.h>
  21. #include "cscp.h"
  22. static FARPROC pCSCFindFirstFile = NULL;
  23. static FARPROC pCSCFindNextFile = NULL;
  24. static FARPROC pCSCFindClose = NULL;
  25. static FARPROC pCSCIsServerOffline = NULL;
  26. //
  27. // Load the cscdll.dll library, and pull out the functions that we need.
  28. //
  29. GetCSCEntryPoints()
  30. {
  31. HANDLE hMod;
  32. if( pCSCFindFirstFile == NULL ) {
  33. //
  34. // Get the entry points in reverse order for multithread protection
  35. //
  36. hMod = LoadLibrary(L"cscdll.dll");
  37. if( hMod == NULL ) {
  38. return 0;
  39. }
  40. pCSCFindClose = GetProcAddress(hMod,"CSCFindClose");
  41. if( pCSCFindClose == NULL ) {
  42. return 0;
  43. }
  44. pCSCFindNextFile = GetProcAddress(hMod,"CSCFindNextFileW" );
  45. if( pCSCFindNextFile == NULL ) {
  46. return 0;
  47. }
  48. pCSCIsServerOffline = GetProcAddress(hMod, "CSCIsServerOfflineW" );
  49. if( pCSCIsServerOffline == NULL ) {
  50. return 0;
  51. }
  52. pCSCFindFirstFile = GetProcAddress(hMod,"CSCFindFirstFileW" );
  53. }
  54. return pCSCFindFirstFile != 0;
  55. }
  56. //
  57. // return TRUE if we think this server is in the offline state
  58. //
  59. BOOLEAN
  60. CSCIsServerOffline(
  61. IN LPWSTR servername
  62. )
  63. {
  64. BOOL isOffline;
  65. if( GetCSCEntryPoints() &&
  66. pCSCIsServerOffline( servername, &isOffline ) &&
  67. isOffline == TRUE ) {
  68. return TRUE;
  69. }
  70. return FALSE;
  71. }
  72. //
  73. // Emulate NetShareEnum() for offline servers
  74. //
  75. NET_API_STATUS NET_API_FUNCTION
  76. CSCNetShareEnum (
  77. IN LPWSTR servername,
  78. IN DWORD level,
  79. OUT LPBYTE *bufptr,
  80. OUT LPDWORD entriesread,
  81. OUT LPDWORD totalentries
  82. )
  83. {
  84. HANDLE hFind = INVALID_HANDLE_VALUE;
  85. WIN32_FIND_DATAW sFind32;
  86. DWORD dwError, dwStatus, dwPinCount, dwHintFlags;
  87. FILETIME ftOrgTime;
  88. NET_API_STATUS apiStatus;
  89. LPWSTR server, share;
  90. PBYTE outbuf = NULL, endp;
  91. DWORD count, numFound, sharelen;
  92. if( (level != 0 && level != 1) ) {
  93. return ERROR_INVALID_PARAMETER;
  94. }
  95. try {
  96. if (servername[0] != L'\\')
  97. {
  98. // OK
  99. }
  100. else if ((servername[0] == L'\\') && (servername[1] == L'\\'))
  101. {
  102. servername += 2;
  103. }
  104. else{
  105. apiStatus = ERROR_NOT_SUPPORTED;
  106. goto try_exit;
  107. }
  108. count = 1024;
  109. retry:
  110. numFound = 0;
  111. //
  112. // Allocate space for the results
  113. //
  114. if( outbuf != NULL ) {
  115. NetApiBufferFree( outbuf );
  116. outbuf = NULL;
  117. count *= 2;
  118. }
  119. apiStatus = NetApiBufferAllocate( count, &outbuf );
  120. if( apiStatus != NO_ERROR ) {
  121. goto try_exit;
  122. }
  123. endp = outbuf + count;
  124. RtlZeroMemory( outbuf, count );
  125. //
  126. // See if we can enumerate the cached servers and shares
  127. //
  128. if( hFind != INVALID_HANDLE_VALUE ) {
  129. pCSCFindClose( hFind );
  130. hFind = INVALID_HANDLE_VALUE;
  131. }
  132. hFind = (HANDLE)pCSCFindFirstFile( NULL,
  133. &sFind32,
  134. &dwStatus,
  135. &dwPinCount,
  136. &dwHintFlags,
  137. &ftOrgTime
  138. );
  139. if( hFind == INVALID_HANDLE_VALUE ) {
  140. NetApiBufferFree( outbuf );
  141. apiStatus = ERROR_NOT_SUPPORTED;
  142. goto try_exit;
  143. }
  144. do {
  145. //
  146. // For each entry, take a look to see if it's one that we want. If
  147. // it is one, pack the results into the output buffer. If the output
  148. // buffer is too small, grow the buffer and start over again.
  149. //
  150. //
  151. // The name returned should be \\server\sharename
  152. //
  153. if( sFind32.cFileName[0] != L'\\' || sFind32.cFileName[1] != L'\\' ||
  154. sFind32.cFileName[2] == L'\0' ) {
  155. //
  156. // We got a strange server name entry
  157. //
  158. continue;
  159. }
  160. server = &sFind32.cFileName[2];
  161. for( share = server; *share && *share != '\\'; share++ );
  162. if( share[0] != '\\' ) {
  163. //
  164. // No share component?
  165. //
  166. continue;
  167. }
  168. //
  169. // NULL terminate the servername
  170. //
  171. *share++ = L'\0';
  172. if( lstrcmpiW( servername, server ) ) {
  173. continue;
  174. }
  175. //
  176. // We've found an entry for this server!
  177. //
  178. for( sharelen = 0; share[sharelen]; sharelen++ ) {
  179. if( share[ sharelen ] == L'\\' )
  180. break;
  181. }
  182. if( sharelen == 0 ) {
  183. //
  184. // No share component?
  185. //
  186. continue;
  187. }
  188. sharelen *= sizeof( WCHAR ); // it's UNICODE
  189. sharelen += sizeof( WCHAR ); // the NULL
  190. if( level == 0 ) {
  191. PSHARE_INFO_0 s0 = (PSHARE_INFO_0)outbuf + numFound;;
  192. if( (PBYTE)(endp - sharelen) < (PBYTE)(s0 + sizeof( s0 )) ) {
  193. goto retry;
  194. }
  195. endp -= sharelen;
  196. RtlCopyMemory( endp, share, sharelen );
  197. s0->shi0_netname = (LPWSTR)endp;
  198. } else {
  199. PSHARE_INFO_1 s1 = (PSHARE_INFO_1)outbuf + numFound;
  200. if( (PBYTE)(endp - sharelen) < (PBYTE)(s1 + sizeof( s1 )) ) {
  201. goto retry;
  202. }
  203. endp -= sharelen;
  204. RtlCopyMemory( endp, share, sharelen );
  205. s1->shi1_netname = (LPWSTR)endp;
  206. s1->shi1_type = STYPE_DISKTREE;
  207. s1->shi1_remark = (LPWSTR)(endp + sharelen - sizeof(WCHAR));
  208. }
  209. numFound++;
  210. } while( pCSCFindNextFile(hFind, &sFind32, &dwStatus, &dwPinCount, &dwHintFlags, &ftOrgTime) );
  211. pCSCFindClose(hFind);
  212. apiStatus = NERR_Success;
  213. if( numFound == 0 ) {
  214. NetApiBufferFree( outbuf );
  215. outbuf = NULL;
  216. }
  217. *bufptr = outbuf;
  218. *entriesread = numFound;
  219. *totalentries = numFound;
  220. try_exit:;
  221. } except( EXCEPTION_EXECUTE_HANDLER ) {
  222. if( outbuf ) {
  223. NetApiBufferFree( outbuf );
  224. }
  225. if( hFind != INVALID_HANDLE_VALUE ) {
  226. pCSCFindClose( hFind );
  227. }
  228. apiStatus = ERROR_INVALID_PARAMETER;
  229. }
  230. return apiStatus;
  231. }
  232. //
  233. // Emulate NetShareGetInfo() for an offline server
  234. //
  235. NET_API_STATUS NET_API_FUNCTION
  236. CSCNetShareGetInfo (
  237. IN LPTSTR servername,
  238. IN LPTSTR netname,
  239. IN DWORD level,
  240. OUT LPBYTE *bufptr
  241. )
  242. {
  243. HANDLE hFind = INVALID_HANDLE_VALUE;
  244. WIN32_FIND_DATAW sFind32;
  245. DWORD dwError, dwStatus, dwPinCount, dwHintFlags;
  246. FILETIME ftOrgTime;
  247. NET_API_STATUS apiStatus = ERROR_NOT_SUPPORTED;
  248. LPWSTR server, share;
  249. DWORD netNameSize;
  250. if( (level != 0 && level != 1) ) {
  251. return ERROR_NOT_SUPPORTED;
  252. }
  253. try {
  254. hFind = (HANDLE)pCSCFindFirstFile( NULL,
  255. &sFind32,
  256. &dwStatus,
  257. &dwPinCount,
  258. &dwHintFlags,
  259. &ftOrgTime
  260. );
  261. if( hFind == INVALID_HANDLE_VALUE ) {
  262. goto try_exit;
  263. }
  264. //
  265. // Loop through the entries until we find one we want
  266. //
  267. do {
  268. server = &sFind32.cFileName[0];
  269. for( share = server; *share && *share != '\\'; share++ );
  270. if( share[0] != '\\' ) {
  271. //
  272. // No share component?
  273. //
  274. continue;
  275. }
  276. //
  277. // NULL terminate the servername
  278. //
  279. *share++ = L'\0';
  280. if( lstrcmpiW( servername, server ) || lstrcmpiW( share, netname ) ) {
  281. continue;
  282. }
  283. for( netNameSize = 0; netname[ netNameSize ]; netNameSize++ )
  284. ;
  285. netNameSize += 1;
  286. netNameSize *= sizeof( WCHAR );
  287. //
  288. // Got the match!
  289. //
  290. if( level == 0 ) {
  291. PSHARE_INFO_0 s0;
  292. apiStatus = NetApiBufferAllocate( sizeof(*s0) + netNameSize, &s0 );
  293. if( apiStatus == NO_ERROR ) {
  294. s0->shi0_netname = (LPTSTR)(s0 + 1);
  295. RtlCopyMemory( s0->shi0_netname, netname, netNameSize );
  296. *bufptr = (LPBYTE)s0;
  297. apiStatus = NERR_Success;
  298. }
  299. } else {
  300. PSHARE_INFO_1 s1;
  301. apiStatus = NetApiBufferAllocate( sizeof(*s1) + netNameSize, &s1 );
  302. if( apiStatus == NO_ERROR ) {
  303. s1->shi1_netname = (LPTSTR)(s1 + 1);
  304. RtlCopyMemory( s1->shi1_netname, netname, netNameSize );
  305. s1->shi1_type = STYPE_DISKTREE;
  306. s1->shi1_remark = s1->shi1_netname + netNameSize/sizeof(WCHAR) - sizeof(WCHAR);
  307. *bufptr = (LPBYTE)s1;
  308. apiStatus = NERR_Success;
  309. }
  310. }
  311. break;
  312. } while( pCSCFindNextFile(hFind,&sFind32,&dwStatus,&dwPinCount,&dwHintFlags, &ftOrgTime) );
  313. pCSCFindClose( hFind );
  314. try_exit:;
  315. } except ( EXCEPTION_EXECUTE_HANDLER ) {
  316. if( hFind != INVALID_HANDLE_VALUE ) {
  317. pCSCFindClose( hFind );
  318. }
  319. apiStatus = ERROR_INVALID_PARAMETER;
  320. }
  321. return apiStatus;
  322. }