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.

193 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. csc.c
  5. Abstract:
  6. These are the wkssvc 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 <lmwksta.h>
  21. #include "cscp.h"
  22. static FARPROC pCSCIsServerOffline = NULL;
  23. /*
  24. * Paranoia
  25. */
  26. #define WCSLEN( x ) ( (x) ? wcslen(x) : 0)
  27. #define WCSCPY( d, s ) (((s) && (d)) ? wcscpy( d, s ) : 0)
  28. //
  29. // Load the cscdll.dll library, and pull out the functions that we need.
  30. //
  31. static
  32. GetCSCEntryPoints()
  33. {
  34. HANDLE hMod;
  35. if( pCSCIsServerOffline == NULL ) {
  36. hMod = LoadLibrary(L"cscdll.dll");
  37. if( hMod != NULL ) {
  38. pCSCIsServerOffline = GetProcAddress(hMod, "CSCIsServerOfflineW" );
  39. }
  40. }
  41. return pCSCIsServerOffline != NULL;
  42. }
  43. //
  44. // Return TRUE if we think this server is in the offline state
  45. //
  46. static
  47. BOOLEAN
  48. CSCIsServerOffline(
  49. IN LPWSTR servername
  50. )
  51. {
  52. BOOL isOffline;
  53. if( GetCSCEntryPoints() &&
  54. pCSCIsServerOffline( servername, &isOffline ) &&
  55. isOffline == TRUE ) {
  56. return TRUE;
  57. }
  58. return FALSE;
  59. }
  60. //
  61. // Emulate NetWkstaGetInfo() for an offline server. We don't capture enough information
  62. // from the target server to really emulate this API, so we use our own data instead.
  63. //
  64. NET_API_STATUS NET_API_FUNCTION
  65. CSCNetWkstaGetInfo (
  66. IN LPTSTR servername,
  67. IN DWORD level,
  68. OUT LPBYTE *bufptr
  69. )
  70. {
  71. NET_API_STATUS status;
  72. PWKSTA_INFO_100 wsi;
  73. ULONG len, baselen;
  74. PVOID ni;
  75. if( CSCIsServerOffline( servername ) == FALSE ) {
  76. return ERROR_UNEXP_NET_ERR;
  77. }
  78. //
  79. // Call the local API, since we don't have cached info for the remote one
  80. //
  81. status = NetWkstaGetInfo( NULL, level, bufptr );
  82. //
  83. // If we got an error or the computername is not in the returned info, then
  84. // just get out now.
  85. //
  86. if( status != NO_ERROR ||
  87. (level != 100 && level != 101 && level != 102 ) ) {
  88. return status;
  89. }
  90. //
  91. // We need to patch the computer name to be the name the caller asked
  92. // for, not the local name
  93. //
  94. wsi = (PWKSTA_INFO_100)(*bufptr);
  95. //
  96. // The returned computer name does not have the leading slashes, so trim them off
  97. //
  98. while( *servername == L'\\' ) {
  99. servername++;
  100. }
  101. if( *servername == L'\0' ) {
  102. MIDL_user_free( *bufptr );
  103. *bufptr = NULL;
  104. return ERROR_UNEXP_NET_ERR;
  105. }
  106. //
  107. // Maybe we can do the substitution in place
  108. //
  109. if( WCSLEN( servername ) <= WCSLEN( wsi->wki100_computername ) ) {
  110. //
  111. // Great -- we can do it in place!
  112. //
  113. WCSCPY( wsi->wki100_computername, servername );
  114. return NO_ERROR;
  115. }
  116. //
  117. // Drat -- we need to reallocate and do it the hard way
  118. //
  119. len = WCSLEN( wsi->wki100_langroup )*sizeof(WCHAR) + sizeof( WCHAR );
  120. len += WCSLEN( servername ) * sizeof( WCHAR ) + sizeof( WCHAR );
  121. switch( level ) {
  122. case 100:
  123. baselen = sizeof( WKSTA_INFO_100 );
  124. break;
  125. case 101:
  126. baselen = sizeof( WKSTA_INFO_101 );
  127. len += WCSLEN( ((PWKSTA_INFO_101)(*bufptr))->wki101_lanroot )* sizeof( WCHAR ) + sizeof( WCHAR );
  128. break;
  129. case 102:
  130. baselen = sizeof( WKSTA_INFO_102 );
  131. len += WCSLEN( ((PWKSTA_INFO_101)(*bufptr))->wki101_lanroot )* sizeof( WCHAR ) + sizeof( WCHAR );
  132. break;
  133. }
  134. if ((ni = MIDL_user_allocate(baselen + len )) == NULL) {
  135. MIDL_user_free( *bufptr );
  136. *bufptr = NULL;
  137. return ERROR_NOT_ENOUGH_MEMORY;
  138. }
  139. memcpy( ni, *bufptr, baselen );
  140. wsi = (PWKSTA_INFO_100)ni;
  141. wsi->wki100_computername = (LPWSTR)((PBYTE)ni + baselen);
  142. WCSCPY( wsi->wki100_computername, servername );
  143. wsi->wki100_langroup = (LPWSTR)((LPBYTE)wsi->wki100_computername +
  144. (WCSLEN( wsi->wki100_computername )+1) * sizeof(WCHAR));
  145. WCSCPY( wsi->wki100_langroup, ((PWKSTA_INFO_100)(*bufptr))->wki100_langroup );
  146. if( level == 101 || level == 102 ) {
  147. PWKSTA_INFO_101 wsi101 = (PWKSTA_INFO_101)ni;
  148. wsi101->wki101_lanroot = (LPWSTR)(((LPBYTE)wsi->wki100_langroup) +
  149. (WCSLEN(wsi->wki100_langroup)+1)*sizeof(WCHAR));
  150. WCSCPY( wsi101->wki101_lanroot, ((PWKSTA_INFO_101)(*bufptr))->wki101_lanroot );
  151. }
  152. MIDL_user_free( *bufptr );
  153. *bufptr = ni;
  154. return NO_ERROR;
  155. }