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.

266 lines
8.8 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. TOD.c
  5. Abstract:
  6. This file contains the RpcXlate code to handle the NetRemote APIs
  7. that can't be handled by simple calls to RxRemoteApi.
  8. Author:
  9. John Rogers (JohnRo) 02-Apr-1991
  10. Environment:
  11. Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
  12. Requires ANSI C extensions: slash-slash comments, long external names.
  13. This code assumes that time_t is expressed in seconds since 1970 (GMT).
  14. ANSI C does not require this, although POSIX (IEEE 1003.1) does.
  15. Revision History:
  16. 02-Apr-1991 JohnRo
  17. Created.
  18. 13-Apr-1991 JohnRo
  19. Moved API handlers into per-group header files (e.g. RxServer.h).
  20. Quiet debug output by default.
  21. Reduced recompile hits from header files.
  22. 03-May-1991 JohnRo
  23. Changed to use both 16-bit data desc and SMB data desc. Use LPTSTR.
  24. Call RxpTransactSmb with UNC server name.
  25. 06-May-1991 JohnRo
  26. Use RxpComputeRequestBufferSize(). Use correct print strings for
  27. server name and descriptors.
  28. 15-May-1991 JohnRo
  29. Added conversion mode handling.
  30. 19-May-1991 JohnRo
  31. Make LINT-suggested changes. Got rid of tabs (again).
  32. 17-Jul-1991 JohnRo
  33. Extracted RxpDebug.h from Rxp.h.
  34. 25-Sep-1991 JohnRo
  35. Handle RapConvertSingleEntry's new return code.
  36. 21-Nov-1991 JohnRo
  37. Removed NT dependencies to reduce recompiles.
  38. 07-Feb-1992 JohnRo
  39. Use NetApiBufferAllocate() instead of private version.
  40. 15-Apr-1992 JohnRo
  41. FORMAT_POINTER is obsolete.
  42. 18-Aug-1992 JohnRo
  43. RAID 2920: Support UTC timezone in net code.
  44. Use PREFIX_ equates.
  45. 01-Oct-1992 JohnRo
  46. RAID 3556: Added NetpSystemTimeToGmtTime() for DosPrint APIs.
  47. 10-Jun-1993 JohnRo
  48. RAID 13081: NetRemoteTOD should return timezone info in right units.
  49. --*/
  50. // These must be included first:
  51. #include <windows.h> // IN, LPTSTR, etc.
  52. #include <lmcons.h>
  53. // These may be included in any order:
  54. #include <apinums.h>
  55. #include <lmapibuf.h> // NetApiBufferFree().
  56. #include <lmerr.h> // NO_ERROR, ERROR_ and NERR_ equates.
  57. #include <lmremutl.h> // Real API prototypes and #defines.
  58. #include <netdebug.h> // NetpKdPrint(()), FORMAT_ equates, etc.
  59. #include <prefix.h> // PREFIX_ equates.
  60. #include <remdef.h> // 16-bit and 32-bit descriptor strings.
  61. #include <rx.h> // RxRemoteApi().
  62. #include <rxpdebug.h> // IF_DEBUG().
  63. #include <rxremutl.h> // My prototype.
  64. #include <time.h> // gmtime(), struct tm, time_t.
  65. #include <timelib.h> // NetpGmtTimeToLocalTime(), NetpLocalTimeZoneOffset().
  66. NET_API_STATUS
  67. RxNetRemoteTOD (
  68. IN LPTSTR UncServerName,
  69. OUT LPBYTE *BufPtr
  70. )
  71. /*++
  72. Routine Description:
  73. RxNetRemoteTOD performs the same function as NetRemoteTOD,
  74. except that the server name is known to refer to a downlevel server.
  75. Arguments:
  76. (Same as NetRemoteTOD, except UncServerName must not be null, and
  77. must not refer to the local computer.)
  78. Return Value:
  79. (Same as NetRemoteTOD.)
  80. --*/
  81. {
  82. NET_API_STATUS ApiStatus;
  83. time_t GmtTime; // seconds since 1970 (GMT).
  84. struct tm * pGmtTm; // broken down GMT time (static obj).
  85. PTIME_OF_DAY_INFO pGmtTod = NULL; // TOD on remote sys, GMT timezone.
  86. LONG LocalTimeZoneOffsetSecs; // offset (+ for West of GMT, etc).
  87. TIME_OF_DAY_INFO LocalTod; // TOD on remote sys, local timezone.
  88. LONG timezone;
  89. NetpAssert(UncServerName != NULL);
  90. IF_DEBUG(REMUTL) {
  91. NetpKdPrint(( PREFIX_NETAPI
  92. "RxNetRemoteTOD: starting, server='" FORMAT_LPTSTR "'.\n",
  93. UncServerName));
  94. }
  95. //
  96. // REM32_time_of_day_info, also used by XACTSRV, translates the
  97. // 16-bit local time returned from the server to GMT. Unfortunately
  98. // it uses the timezone of the local machine rather than the timezone
  99. // returned from the server. So, we have our own define here, which
  100. // uses 'J'instead of 'G' so that no translation takes place. Then
  101. // we do our own translation below. This makes us work with
  102. // Windows 95 servers.
  103. #define REM32_time_of_day_info_2 "JDDDDDXDDDDD"
  104. //
  105. // Get TOD structure (with local time values) from other system.
  106. // Note that the "tod_elapsedt" field will be converted from local
  107. // timezone to GMT by RxRemoteApi.
  108. //
  109. ApiStatus = RxRemoteApi(
  110. API_NetRemoteTOD, // API number
  111. (LPTSTR) UncServerName,
  112. REMSmb_NetRemoteTOD_P, // parm desc
  113. REM16_time_of_day_info, // DataDesc16
  114. REM32_time_of_day_info_2, // DataDesc32
  115. REMSmb_time_of_day_info, // DataDescSmb
  116. NULL, // no AuxDesc16
  117. NULL, // no AuxDesc32
  118. NULL, // no AuxDescSmb
  119. 0, // flags: not a null session API
  120. // rest of API's arguments, in 32-bit LM2.x format:
  121. (LPVOID) & LocalTod, // pbBuffer
  122. sizeof(LocalTod) ); // cbBuffer
  123. IF_DEBUG(REMUTL) {
  124. NetpKdPrint(( PREFIX_NETAPI
  125. "RxNetRemoteTOD: after RxRemoteApi, "
  126. "ApiStatus=" FORMAT_API_STATUS ".\n", ApiStatus));
  127. }
  128. if (ApiStatus != NO_ERROR) {
  129. goto Cleanup;
  130. }
  131. //
  132. // Get info on the timezone itself. If target machine doesn't know, then
  133. // we have to fall back on the age-old policy: assume it is running in
  134. // same timezone that we are.
  135. //
  136. if (LocalTod.tod_timezone == -1) {
  137. //
  138. // First, get number of seconds from UTC. (Positive values for
  139. // west of Greenwich, negative values for east of Greenwich.)
  140. // Then, convert to minutes.
  141. LocalTimeZoneOffsetSecs = NetpLocalTimeZoneOffset();
  142. timezone = LocalTimeZoneOffsetSecs / 60;
  143. }
  144. else
  145. {
  146. timezone = LocalTod.tod_timezone;
  147. }
  148. //
  149. // Get GmtTime (time in seconds since 1970, GMT) for convenience.
  150. //
  151. NetpAssert( sizeof(DWORD) == sizeof(time_t) );
  152. GmtTime = (time_t) LocalTod.tod_elapsedt + timezone * 60;
  153. IF_DEBUG(REMUTL) {
  154. NetpKdPrint(( PREFIX_NETAPI
  155. "RxNetRemoteTOD: before convert, buffer:\n"));
  156. NetpDbgDisplayTod( "before GMT conv", & LocalTod );
  157. NetpDbgDisplayTimestamp( "secs since 1970 (GMT)", (DWORD) GmtTime );
  158. }
  159. NetpAssert( GmtTime != 0 );
  160. NetpAssert( GmtTime != (time_t) (-1) );
  161. //
  162. // Alloc area for converted time of day info.
  163. // API's caller will free this with NetApiBufferFree().
  164. //
  165. ApiStatus = NetApiBufferAllocate(
  166. sizeof(TIME_OF_DAY_INFO),
  167. (LPVOID *) (LPVOID) & pGmtTod );
  168. if (ApiStatus != NO_ERROR) {
  169. NetpAssert( pGmtTod == NULL );
  170. goto Cleanup;
  171. }
  172. NetpAssert( pGmtTod != NULL );
  173. //
  174. // Convert LocalTod fields to UTC timezone and set pGmtTod fields.
  175. // This depends on the POSIX semantics of gmtime().
  176. //
  177. pGmtTm = gmtime( (time_t *) &(GmtTime) );
  178. if (pGmtTm == NULL) {
  179. // UTC not available? How can this happen?
  180. NetpKdPrint(( PREFIX_NETAPI
  181. "RxNetRemoteTOD: gmtime() failed!.\n" ));
  182. ApiStatus = NERR_InternalError;
  183. goto Cleanup;
  184. }
  185. pGmtTod->tod_elapsedt = (DWORD) GmtTime;
  186. pGmtTod->tod_msecs = LocalTod.tod_msecs;
  187. pGmtTod->tod_hours = pGmtTm->tm_hour;
  188. pGmtTod->tod_mins = pGmtTm->tm_min;
  189. if (pGmtTm->tm_sec <= 59) {
  190. // Normal.
  191. pGmtTod->tod_secs = pGmtTm->tm_sec;
  192. } else {
  193. // Leap second. Lie and say that it's not. This will avoid possible
  194. // range problems in apps that only expect 0..59, as the
  195. // TIME_OF_DAY_INFO struct is documented in LM 2.x.
  196. pGmtTod->tod_secs = 59;
  197. }
  198. pGmtTod->tod_hunds = LocalTod.tod_hunds;
  199. pGmtTod->tod_tinterval = LocalTod.tod_tinterval;
  200. pGmtTod->tod_day = pGmtTm->tm_mday;
  201. pGmtTod->tod_month = pGmtTm->tm_mon + 1; // month (0..11) to (1..12)
  202. pGmtTod->tod_year = pGmtTm->tm_year + 1900;
  203. pGmtTod->tod_weekday = pGmtTm->tm_wday;
  204. pGmtTod->tod_timezone = timezone;
  205. IF_DEBUG(REMUTL) {
  206. NetpKdPrint(( PREFIX_NETAPI
  207. "RxNetRemoteTOD: after convert, buffer:\n"));
  208. NetpDbgDisplayTod( "after GMT conv", pGmtTod );
  209. }
  210. Cleanup:
  211. if (ApiStatus == NO_ERROR) {
  212. *BufPtr = (LPBYTE) (LPVOID) pGmtTod;
  213. } else if (pGmtTod != NULL) {
  214. (VOID) NetApiBufferFree( pGmtTod );
  215. }
  216. return (ApiStatus);
  217. } // RxNetRemoteTOD