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.

217 lines
7.0 KiB

  1. // Replace:
  2. // {capgroup} is the name of group in caps as it appears in typedefs.
  3. // {date} with today's date in dd-Mmm-yyyy form.
  4. // {email} with your email ID.
  5. // {filename} with name of this file (including .c at end)
  6. // {fullname} with your full name
  7. // {header} is the header file name part (e.g. "wksta" in lmwksta.h)
  8. // {icgroup} is name of group with initial caps, e.g. "Server".
  9. // Take care of all {expand} replacements.
  10. // Delete these instructions.
  11. /*++
  12. Copyright (c) 1991-1993 Microsoft Corporation
  13. Module Name:
  14. {filename}
  15. Abstract:
  16. This file contains the RpcXlate code to handle the Net{icgroup}Enum API.
  17. Author:
  18. {fullname} ({email}) {date}
  19. Environment:
  20. Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
  21. Requires ANSI C extensions: slash-slash comments, long external names.
  22. Revision History:
  23. {date} {email}
  24. Created.
  25. --*/
  26. // These must be included first:
  27. #include <windef.h> // IN, DWORD, etc.
  28. #include <lmcons.h> // DEVLEN, NET_API_STATUS, etc.
  29. // These may be included in any order:
  30. #include <apinums.h> // API_ equates.
  31. #include <lmapibuf.h> // NetapipBufferAllocate(), NetApiBufferFree().
  32. #include <lm{header}.h> // API's data structures.
  33. #include <netdebug.h> // NetpKdPrint(), FORMAT_ equates.
  34. #include <netlib.h> // NetpAdjustPreferredMaximum().
  35. #include <rap.h> // LPDESC.
  36. #include <remdef.h> // REM16_, REM32_, REMSmb_ equates.
  37. #include <rx.h> // RxRemoteApi().
  38. #include <rxp.h> // MAX_TRANSACT_RET_DATA_SIZE, RxpFatalErrorCode().
  39. #include <rx{header}.h> // My prototype(s).
  40. #include <strucinf.h> // Netp{icgroup}StructureInfo().
  41. #include <winerror.h> // NO_ERROR and ERROR_ equates.
  42. #define {capgroup}_ARRAY_OVERHEAD_SIZE 0
  43. NET_API_STATUS
  44. RxNet{icgroup}Enum (
  45. IN LPTSTR UncServerName,
  46. {expand},
  47. IN DWORD Level,
  48. OUT LPBYTE *BufPtr,
  49. IN DWORD PreferedMaximumSize,
  50. OUT LPDWORD EntriesRead,
  51. OUT LPDWORD TotalEntries,
  52. IN OUT LPDWORD ResumeHandle OPTIONAL
  53. )
  54. /*++
  55. Routine Description:
  56. RxNet{icgroup}Enum performs the same function as Net{icgroup}Enum,
  57. except that the server name is known to refer to a downlevel server.
  58. Arguments:
  59. (Same as Net{icgroup}Enum, except UncServerName must not be null, and
  60. must not refer to the local computer.)
  61. Return Value:
  62. (Same as Net{icgroup}Enum.)
  63. --*/
  64. {
  65. LPDESC DataDesc16;
  66. LPDESC DataDesc32;
  67. LPDESC DataDescSmb;
  68. DWORD EntriesToAllocate;
  69. LPVOID InfoArray;
  70. DWORD InfoArraySize;
  71. DWORD MaxEntrySize;
  72. NET_API_STATUS Status;
  73. UNREFERENCED_PARAMETER(ResumeHandle);
  74. // Make sure caller didn't mess up.
  75. NetpAssert(UncServerName != NULL);
  76. if (BufPtr == NULL) {
  77. return (ERROR_INVALID_PARAMETER);
  78. }
  79. // Assume something might go wrong, and make error paths easier to
  80. // code. Also, check for bad pointers before we do anything.
  81. *BufPtr = NULL;
  82. *EntriesRead = 0;
  83. *TotalEntries = 0;
  84. Status = Netp{icgroup}StructureInfo (
  85. Level,
  86. PARMNUM_ALL, // want all fields.
  87. TRUE, // want native sizes.
  88. & DataDesc16,
  89. & DataDesc32,
  90. & DataDescSmb,
  91. & MaxEntrySize, // API buffer size 32
  92. NULL, // don't need fixed size
  93. NULL // don't need string size
  94. );
  95. if (Status != NO_ERROR) {
  96. *BufPtr = NULL;
  97. return (Status);
  98. }
  99. //
  100. // Downlevel servers don't support resume handles, and we don't
  101. // have a way to say "close this resume handle" even if we wanted to
  102. // emulate them here. Therefore we have to do everthing in one shot.
  103. // So, the first time around, we'll try using the caller's prefered
  104. // maximum, but we will enlarge that until we can get everything in one
  105. // buffer.
  106. //
  107. // First time: try caller's prefered maximum.
  108. NetpAdjustPreferedMaximum (
  109. PreferedMaximumSize, // caller's request
  110. MaxEntrySize, // byte count per array element
  111. {capgroup}_ARRAY_OVERHEAD_SIZE, // num bytes overhead to show array end
  112. NULL, // we'll compute byte counts ourselves.
  113. & EntriesToAllocate); // num of entries we can get.
  114. //
  115. // Loop until we have enough memory or we die for some other reason.
  116. //
  117. do {
  118. // Figure out how much memory we need.
  119. InfoArraySize = (EntriesToAllocate * MaxEntrySize)
  120. + {capgroup}_ARRAY_OVERHEAD_SIZE;
  121. //
  122. // adjust the size to the maximum amount a down-level server
  123. // can handle
  124. //
  125. if (InfoArraySize > MAX_TRANSACT_RET_DATA_SIZE) {
  126. InfoArraySize = MAX_TRANSACT_RET_DATA_SIZE;
  127. }
  128. //
  129. // Remote the API, which will allocate the array for us.
  130. //
  131. Status = RxRemoteApi(
  132. API_W{icgroup}Enum, // api number
  133. UncServerName, // \\servername
  134. REMSmb_Net{icgroup}Enum_P, // parm desc (SMB version)
  135. DataDesc16,
  136. DataDesc32,
  137. DataDescSmb,
  138. NULL, // no aux desc 16
  139. NULL, // no aux desc 32
  140. NULL, // no aux desc SMB
  141. ALLOCATE_RESPONSE, // flags: allocate buffer for us
  142. // rest of API's arguments in 32-bit LM 2.x format:
  143. {expand}
  144. Level, // sLevel: info level
  145. & InfoArray, // Buffer: array (alloc for us)
  146. InfoArraySize, // Buffer: array size in bytes
  147. EntriesRead, // pcEntriesRead
  148. TotalEntries); // pcTotalAvail
  149. if (Status == ERROR_MORE_DATA) {
  150. NetpAssert( InfoArraySize <= MAX_TRANSACT_RET_DATA_SIZE );
  151. if (InfoArraySize == MAX_TRANSACT_RET_DATA_SIZE) {
  152. NetpKdPrint(( PREFIX_NETAPI
  153. "RxNet{icgroup}Enum: "
  154. "**WARNING** protocol limit reached (64KB).\n" ));
  155. break;
  156. }
  157. (VOID) NetApiBufferFree( InfoArray );
  158. NetpAssert( EntriesToAllocate < *TotalEntries );
  159. EntriesToAllocate = *TotalEntries;
  160. }
  161. } while (Status == ERROR_MORE_DATA);
  162. if ( (Status == NO_ERROR) && ((*EntriesRead) > 0) ) {
  163. *BufPtr = InfoArray;
  164. } else {
  165. (VOID) NetApiBufferFree( InfoArray );
  166. NetpAssert( *BufPtr == NULL );
  167. }
  168. return (Status);
  169. } // RxNet{icgroup}Enum