mirror of https://github.com/lianthony/NT4.0
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.
556 lines
17 KiB
556 lines
17 KiB
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
local.h
|
|
|
|
Abstract:
|
|
|
|
Main include file for Remote initial Program Load service.
|
|
|
|
Author:
|
|
|
|
Vladimir Z. Vulovic (vladimv) 19 - November - 1993
|
|
|
|
Environment:
|
|
|
|
User mode
|
|
|
|
Revision History :
|
|
|
|
--*/
|
|
|
|
#include <nt.h> // ntexapi.h\NtQuerySystemTime
|
|
#include <ntrtl.h> // RtlTimeToSecondsSince1970
|
|
#include <nturtl.h>
|
|
|
|
#include <windows.h> // DWORD, IN, File APIs, etc.
|
|
#include <stdlib.h>
|
|
#include <lmcons.h>
|
|
|
|
#include <stdio.h> // vsprintf
|
|
#include <ctype.h> // isspace
|
|
|
|
#include <lmerr.h> // NERR_RplBootStartFailed - used to be here
|
|
#include <lmapibuf.h> // NetApiBufferFree
|
|
#include <netlib.h>
|
|
|
|
#include <lmsvc.h>
|
|
|
|
#include <lmalert.h> // STD_ALERT ALERT_OTHER_INFO
|
|
|
|
#include <lmerrlog.h>
|
|
#include <alertmsg.h>
|
|
#include <lmserver.h>
|
|
#include <netlib.h>
|
|
#include <netlock.h> // Lock data types, functions, and macros.
|
|
#include <thread.h> // FORMAT_NET_THREAD_ID, NetpCurrentThread().
|
|
|
|
#include <lmshare.h> // PSHARE_INFO_2
|
|
#include <lmaccess.h> // NetGroupGetInfo
|
|
#include <lmconfig.h> // NetConfigGet
|
|
#include <nb30.h> // NCB
|
|
|
|
|
|
//
|
|
// Global types and constants (used in all RPL server files).
|
|
//
|
|
|
|
#include <riplcons.h> // includes __JET500 flag
|
|
#include <jet.h>
|
|
#include <rpldebug.h>
|
|
#include <rpldll.h> // rplnet.dll entry points & return codes
|
|
#include <rpllib.h> // AddKey(), MapJetError(), FillTcpIpString()
|
|
#include <ripltyps.h>
|
|
|
|
#include <rpc.h> // DataTypes and runtime APIs
|
|
#include <rpcutil.h> // Prototypes for MIDL user functions
|
|
//
|
|
// rplsvc_s.h includes imports.h which includes lmrpl.h. This allows us
|
|
// to use API-related DS in the rest of the service code.
|
|
//
|
|
#include <rplsvc_s.h> // Generated by the MIDL complier
|
|
|
|
|
|
//
|
|
// Other defines
|
|
//
|
|
|
|
#define DOUBLE_BACK_SLASH_STRING L"\\\\"
|
|
|
|
//
|
|
// BITMASK to be used with Flags field in RPL_WKSTA data structure
|
|
//
|
|
#define RPL_WKSTA_PERSONAL 0x01
|
|
|
|
#define MAX_ADAPTERS 12 // "rpl1" through "rpl12"
|
|
|
|
|
|
#define MIN_BBLOCK_BASE 0xc00
|
|
|
|
//
|
|
// All BBC files are very small, typically around 1K.
|
|
// Use 32K as the absolute maximum on BBC file size.
|
|
//
|
|
#define MAX_BBC_FILE_SIZE 0x8000 // for no compelling reason
|
|
|
|
#define MAX_FIT_FILE_SIZE 0xF000 // some arbitrary value
|
|
#define MAX_SIZEOF_DBCS_PATH (PATHLEN *sizeof(WCHAR)+sizeof(CHAR))
|
|
|
|
#define SERVER_LINE_ID_LEN 12
|
|
|
|
#define DEFAULT_RETRY_COUNT 3
|
|
#define DEFAULT_RETRY_TIMEOUT 10
|
|
#define DEFAULT_WINDOW_SIZE MAXWORD
|
|
#define DEFAULT_SEND_FINAL_REQ FALSE
|
|
|
|
#define MAX_XMIT_ERRORS 30 // max contiguous fatal xmit failures
|
|
|
|
//
|
|
// status bits of main_action_status
|
|
//
|
|
|
|
#define TERMINATE_SERVICE 1
|
|
#define REINITIALIZE_SERVICE 2
|
|
#define REINITIALIZATION_PENDING 4
|
|
#define TERMINATION_PENDING 8
|
|
|
|
#define ERROR_HANDLING (DWORD)(-1)
|
|
#define NO_ERROR_HANDLING 0
|
|
#define MAX_OPEN_RETRY 40
|
|
#define MAX_OEM_NAME 7
|
|
|
|
//
|
|
// Constants of the actual ripl server
|
|
//
|
|
|
|
#define RPL_DLL_SKELETON "rpl"
|
|
#define WORKER_THREAD_MIN 2
|
|
#define MAX_FRAME_SIZE 0x1000 // exactly 1 page, or 4KB
|
|
#define MAX_SUB_SEGMENT_SIZE 0xffe0
|
|
#define SEND_BUF_SEG_SIZE 17000
|
|
//
|
|
// MAX_ADAPTER_INFO_SIZE is now defined to be the sum of upper size
|
|
// estimates for DLC buffer (0xA000) and private adapter info (2000).
|
|
//
|
|
#define MAX_ADAPTER_INFO_SIZE (0xA000 + 2000)
|
|
|
|
#define LAN_ADAPTER0 0
|
|
#define CHECK_SUM_ERROR 9676
|
|
#define SF_REQ_TIMEOUT 7 //IBM waits 3s for lost frame & (ACK lost)
|
|
#define MAX_FILE_HANDLES_INC 20 // increment of max fhs
|
|
#define UNINSTALL_TIME 100 // 10 seconds, actually: (1 - 150)
|
|
|
|
#define RPL_KEYBOARD_DCP L"KEYBOARD.DCP"
|
|
#define RIPL_CHECK_SUM L"rplchecksum"
|
|
#define RPLDIR_DEF L"rpldir"
|
|
#define RPL_DIR_1 L"rpl1"
|
|
#define YES L"yes"
|
|
#define RPL_LOGON_KBD L"rpllogonkbd"
|
|
#define LANMAN_INI L"lanman.ini"
|
|
#define RPL_REMARK L"Remoteboot service share"
|
|
#define RPLUSER_GROUP L"RPLUSER"
|
|
|
|
//
|
|
// JETBUG entries are needed for workaround for JetMakeKey-JetSeek bug.
|
|
// If this bug gets ever fixed, they should be removed (undef RPL_JETBUG)
|
|
//
|
|
#define RPL_JETBUG
|
|
#ifdef RPL_JETBUG
|
|
#define JETBUG_STRING L" "
|
|
#define JETBUG_STRING_SIZE sizeof( JETBUG_STRING)
|
|
#define JETBUG_STRING_LENGTH ((DWORD)(sizeof( JETBUG_STRING)/sizeof(WCHAR) - 1))
|
|
#else
|
|
#define JETBUG_STRING_LENGTH 0
|
|
#endif
|
|
|
|
//
|
|
// TIMEOUTS
|
|
//
|
|
|
|
#define GET_SF_REQUEST_TIMEOUT 6000L // not error and quite common
|
|
|
|
// implement this with fast retries
|
|
#define LONG_WAIT_ACK_TIMEOUT 30000L // wksta sent no resend requests!
|
|
#define WAIT_ACK_TIMEOUT 1000L // short wait for the lost frames
|
|
|
|
#define MAX_ERR_COUNT 4
|
|
#define MAX_RETRIES 5 // retry count before termination
|
|
|
|
#define OFFSET_BUF_LEN 64 // space for the whole RPLBoot hdr
|
|
|
|
/*++
|
|
RPL service must send NLS (DBCS ??) messages in a layout expected by RPL client
|
|
(from rplboot\rplboot.asm):
|
|
|
|
;------------------------------------------------------------------------
|
|
; NLS messages structure - used in RPLOADR and DLCBOOT
|
|
;------------------------------------------------------------------------
|
|
nlsmsglen equ 80 ;max number of bytes per msg
|
|
nlsmsg struc
|
|
db nlsmsglen dup(' '); ;<space fill>
|
|
db 0dh ;<cr>
|
|
db 0ah ;<lr>
|
|
db '$' ;<terminator>
|
|
nlsmsg ends
|
|
--*/
|
|
|
|
#define DBCS_SINGLE_MESSAGE_BUFFER_SIZE 83
|
|
|
|
//
|
|
// Typedefs
|
|
//
|
|
|
|
typedef struct _FLIST_TBL {
|
|
//
|
|
// UNICODE name. Used for work on the server.
|
|
//
|
|
LPWSTR FileName;
|
|
//
|
|
// Same file name but without path and in DBCS. Sent to client.
|
|
//
|
|
LPSTR DbcsFileName;
|
|
DWORD DbcsFileNameSize;
|
|
|
|
//
|
|
//
|
|
// Size of memory needed for "param_list", not counting terminating null
|
|
// byte, is kept in FILE_DATA.param_len entry.
|
|
//
|
|
LPSTR param_list; // a DBCS string, UNICODE version not needed
|
|
LPWSTR path_name;
|
|
FILE_DATA FileData; // structure to be saved to dump_tbl
|
|
} FLIST_TBL, *PFLIST_TBL;
|
|
|
|
typedef struct _CONFIG_TYPE {
|
|
LPWSTR id;
|
|
DWORD type;
|
|
} CONFIG_TYPE, *PCONFIG_TYPE;
|
|
|
|
#define FIT_ALIAS_ARRAY_LENGTH 7 // poor initialization
|
|
|
|
typedef struct _FIT_ALIAS {
|
|
LPWSTR Key; // keyword, or macro
|
|
LPWSTR Value; // replacement value for the keyword
|
|
DWORD KeyLength; // length of keyword, or macro
|
|
DWORD ValueLength; // length of replacement value for the keyword
|
|
} FIT_ALIAS, *PFIT_ALIAS;
|
|
|
|
|
|
//
|
|
// parameters sent to worker thread
|
|
//
|
|
// thread_id should be initialized somewhere via GetCurrentThreadId()
|
|
//
|
|
|
|
struct _RPL_REQUEST_PARAMS;
|
|
typedef struct _RPL_REQUEST_PARAMS RPL_REQUEST_PARAMS, *PRPL_REQUEST_PARAMS;
|
|
|
|
struct _RPL_WORKER_PARAMS;
|
|
typedef struct _RPL_WORKER_PARAMS RPL_WORKER_PARAMS, *PRPL_WORKER_PARAMS;
|
|
|
|
typedef struct _RPL_REQUEST_PARAMS {
|
|
PRPL_REQUEST_PARAMS pRequestParams; // next in a queue of request threads
|
|
HANDLE ThreadHandle;
|
|
DWORD ThreadId;
|
|
PRPL_WORKER_PARAMS pWorkerParams; // first in a queue of worker threads
|
|
POPEN_INFO pOpenInfo; // generic rpl DLL info
|
|
PRCB FreeRcbList; // list of free rcb blocks
|
|
PRCB BusyRcbList; // list of reserved RCBs
|
|
BOOL Exiting;
|
|
} RPL_REQUEST_PARAMS , *PRPL_REQUEST_PARAMS;
|
|
|
|
typedef struct _RPL_WORKER_PARAMS { // worker thread parameters
|
|
PRPL_WORKER_PARAMS pWorkerParams; // next in a queue of worker threads
|
|
HANDLE ThreadHandle;
|
|
DWORD ThreadId;
|
|
PRPL_REQUEST_PARAMS pRequestParams;
|
|
PRCB pRcb;
|
|
BOOL Exiting;
|
|
} RPL_WORKER_PARAMS, *PRPL_WORKER_PARAMS;
|
|
|
|
typedef struct _RPL_WORKER_DATA {
|
|
//
|
|
// These are addresses of on the stack variables from the Request thread.
|
|
//
|
|
PPRCB pFreeRcbList; // base of free rcb list
|
|
PPRCB pBusyRcbList; // base of reserved rcbs
|
|
//
|
|
// The following three pointers are allocated via RG_MemoryHandle.
|
|
// Everything else in this data structure, including the structure itself
|
|
// is allocated via WORKER_DATA.MemoryHandle == WORKER_PARAMS.MemoryHandle.
|
|
//
|
|
PRCB pRcb; // resource control block
|
|
PRPL_REQUEST_PARAMS pRequestParams; // ptr to request threads parm block
|
|
POPEN_INFO pOpenInfo; // open info of the cur RPL DLL
|
|
//
|
|
// The following are the entries read from database.
|
|
// WkstaName & TcpIp* are sent to the client in wksta line.
|
|
// WkstaName & ProfileName are used to make changes in fit file.
|
|
//
|
|
WCHAR WkstaName[ RPL_MAX_WKSTA_NAME_LENGTH + 1];
|
|
WCHAR ProfileName[ RPL_MAX_PROFILE_NAME_LENGTH + 1];
|
|
DWORD TcpIpAddress;
|
|
DWORD TcpIpSubnet;
|
|
DWORD TcpIpGateway;
|
|
WCHAR LogonInput;
|
|
CHAR DisableDhcp; // '1' ('0') if DHCP is disabled (enabled)
|
|
DWORD WindowSize;
|
|
BOOL FinalAck; // SendFinalRequest;
|
|
|
|
HANDLE MemoryHandle; // for worker thread
|
|
LPBYTE WkstaLine; // old style, RPL.MAP line
|
|
|
|
//
|
|
// Fields describing the boot block configuration file.
|
|
//
|
|
LPWSTR BbcFile; // full path to BBC file
|
|
PFLIST_TBL flist_tbl; // files sent to RPLBOOT
|
|
BOOL MakePatch; // TRUE if patch to RPLBOOT.SYS is needed
|
|
DWORD PatchOffset; // relevant if MakePatch is TRUE
|
|
PRESOURCE_TBL resource_tbl; // file list given to the loader
|
|
PBYTE id_str; // id string of the server
|
|
DWORD min_wksta_buf; // min size of wksta specific data
|
|
DWORD file_block_base; // relative addr of file block in boot block
|
|
DWORD boot_block_base; // base phys addr of boot block
|
|
DWORD flist_tbl_len;
|
|
DWORD loader_i; // index of OS/2 loader in flist_tbl
|
|
DWORD rplboot_i; // index of rplboot.sys in file list
|
|
DWORD resource_tbl_size; // size of the table (in bytes)
|
|
LPWSTR LineBuffer; // used for parsing a line into words
|
|
DWORD LineBufferSize; // size of LineBuffer
|
|
LPWSTR * WordTable; // used for parsing a line into words
|
|
|
|
//
|
|
// Fields describing the file index table file.
|
|
//
|
|
// In order to get full path to fit file we need to check wksta flags
|
|
// to find out profile type (personal or shared) then read the
|
|
// corresponding file path from profile record.
|
|
//
|
|
LPWSTR FitFile; // full path to FIT file
|
|
LPSTR ClientFit; // string with DBCS content of FIT file sent to client
|
|
DWORD ClientFitSize; // size of above string
|
|
FIT_ALIAS FitAliasArray[ FIT_ALIAS_ARRAY_LENGTH];
|
|
|
|
|
|
//
|
|
// Fields initalized (wksta_buf also created) in RplMakeWkstaBuf()
|
|
//
|
|
//
|
|
// wksta_buf contains BOOT_DATA, old RPL.MAP workstation line, processed FIT file,
|
|
// BOOT_BLOCK_HDR and multiboot array.
|
|
//
|
|
// It does not contain files mentioned in boot block configuration file.
|
|
//
|
|
PBYTE wksta_buf; // ptr to wksta specific data
|
|
|
|
//
|
|
// size of wksta_buf
|
|
//
|
|
DWORD wksta_buf_len; // size in bytes of wksta specific data
|
|
|
|
//
|
|
//
|
|
//
|
|
DWORD base_address; // start address of buffer, first send
|
|
DWORD jump_address; // start address of program, last send
|
|
DWORD fblock_base_offset; // base offset (from 0) of file block
|
|
|
|
DWORD send_buf_len; // length of network send buffer
|
|
|
|
//
|
|
// The following group of fields is used while reading data from
|
|
// files mentioned in the boot block configuration file. These
|
|
// fields are initialized in RplOpenData()
|
|
//
|
|
|
|
//
|
|
// "pDataBuffer" is used to read data from disk files, then to send this
|
|
// data to a remote client.
|
|
//
|
|
PBYTE pDataBuffer; // read data here, then send it out
|
|
DWORD cur_flist_i; // current index for FLIST_TBL array
|
|
DWORD cur_offset; // current offset of boot block
|
|
DWORD cur_file_base_offset; // base offset of the current file
|
|
BOOL is_end_of_bblock; // set if end of boot block
|
|
HANDLE hFile; // current file handle
|
|
//
|
|
// ChecksumBuffer - buffer used to checksum files, when checksums are needed.
|
|
//
|
|
PBYTE ChecksumBuffer; // used to checksum files when
|
|
DWORD EventId;
|
|
PWCHAR EventStrings[ 5]; // null terminated
|
|
} RPL_WORKER_DATA, *PRPL_WORKER_DATA;
|
|
|
|
|
|
#define NOTIFY_WKSTA_RECORD 0 // disabled wksta record for main thread to write to RPL.map
|
|
|
|
typedef struct _ADMIN_ALERT_DATA{
|
|
DWORD alrtad_errcode;
|
|
DWORD alrtad_numstrings;
|
|
} ADMIN_ALERT_DATA;
|
|
|
|
typedef struct _ADAPTER_STATUS_BUFFER {
|
|
DWORD id_low;
|
|
DWORD id_mid;
|
|
DWORD id_high;
|
|
BYTE jumper_status;
|
|
BYTE self_test;
|
|
DWORD sw_version;
|
|
BYTE error_statistics[48];
|
|
DWORD name_tbl_len;
|
|
BYTE name1[18];
|
|
BYTE name2[18];
|
|
BYTE name3[18];
|
|
BYTE name4[18];
|
|
BYTE name5[18];
|
|
BYTE name6[18];
|
|
BYTE name7[18];
|
|
BYTE name8[18];
|
|
BYTE name9[18];
|
|
BYTE name10[18];
|
|
BYTE name11[18];
|
|
BYTE name12[18];
|
|
BYTE name13[18];
|
|
BYTE name14[18];
|
|
BYTE name15[18];
|
|
BYTE name16[18];
|
|
} ADAPTER_STATUS_BUFFER;
|
|
|
|
typedef enum {IMMEDIATE_ERROR, WAIT_RESOURCES} BLOCKTYPE;
|
|
|
|
#ifdef UNICODE
|
|
|
|
#define RPL_TO_UNICODE( arg) arg
|
|
#define RPL_FREE_UNICODE( arg)
|
|
|
|
#else // UNICODE
|
|
|
|
WCHAR * RplAsciizToUnicodez( IN CHAR * Asciiz);
|
|
VOID RplFreeUnicodez( IN WCHAR * Unicodez);
|
|
#define RPL_TO_UNICODE( arg) RplAsciizToUnicodez( arg)
|
|
#define RPL_FREE_UNICODE( arg) RplFreeUnicodez( arg)
|
|
|
|
#endif // UNICODE
|
|
|
|
|
|
#define ALERT_LONG_WAIT 10000L // used to be in alert.h
|
|
|
|
//
|
|
// Bitmask used with RG_Tasks. They describe outstanding tasks to be
|
|
// done by the main rpl service thread once it wakes up.
|
|
//
|
|
|
|
#define RPL_SERVICE_SHUTDOWN 0x0004
|
|
|
|
|
|
#define RPL_WAIT_HINT_TIME 15000L // 15 seconds for now
|
|
|
|
|
|
|
|
|
|
#define TMPFILES_IDX 4
|
|
#define BINFILES_IDX 5
|
|
|
|
|
|
//
|
|
// termination addresses of all rpl DLLs have been saved to this list
|
|
//
|
|
|
|
typedef DWORD ( * TERMINATION_ADDRESS)( POPEN_INFO);
|
|
|
|
typedef struct _TERM_LIST {
|
|
struct _TERM_LIST * next;
|
|
POPEN_INFO pOpenInfo;
|
|
} TERM_LIST, *PTERM_LIST;
|
|
|
|
|
|
#define INVALID_ERROR_PARAMETER ((DWORD)(-1)) // internal usage in api code
|
|
|
|
typedef struct _RPL_SESSION {
|
|
JET_SESID SesId; // jet session identifier
|
|
JET_DBID DbId; // jet database identifier
|
|
JET_TABLEID AdapterTableId;
|
|
JET_TABLEID BootTableId;
|
|
JET_TABLEID ConfigTableId;
|
|
JET_TABLEID ProfileTableId;
|
|
JET_TABLEID ResumeTableId;
|
|
JET_TABLEID VendorTableId;
|
|
JET_TABLEID WkstaTableId;
|
|
} RPL_SESSION, *PRPL_SESSION;
|
|
|
|
|
|
//
|
|
// Function Prototypes
|
|
//
|
|
|
|
//
|
|
// memory.c
|
|
//
|
|
|
|
DWORD RplMemInit( PHANDLE pMemoryHandle);
|
|
|
|
PVOID RplMemAlloc(
|
|
IN HANDLE MemoryHandle,
|
|
IN DWORD size
|
|
);
|
|
|
|
VOID RplMemFree(
|
|
IN HANDLE MemoryHandle,
|
|
IN PVOID mem_ptr
|
|
);
|
|
|
|
VOID RplMemClose( IN HANDLE MemoryHandle);
|
|
|
|
PVOID RplMemReAlloc(
|
|
IN HANDLE MemoryHandle,
|
|
IN DWORD Flags,
|
|
IN PVOID old_ptr,
|
|
IN DWORD new_size
|
|
);
|
|
|
|
|
|
//
|
|
// library.c
|
|
//
|
|
|
|
LPWSTR RplGetLastPathComponent( IN LPWSTR FilePath);
|
|
HANDLE RplFileOpen( IN LPWSTR FilePath);
|
|
|
|
LPWSTR RplReadTextFile(
|
|
IN HANDLE MemoryHandle,
|
|
IN LPWSTR FileName,
|
|
IN DWORD MaxFileSize
|
|
);
|
|
DWORD RplUnicodeToDbcs(
|
|
IN HANDLE MemoryHandle,
|
|
IN LPWSTR UnicodeString,
|
|
IN INT UnicodeStringLength,
|
|
IN DWORD MaxDbcsStringSize,
|
|
OUT LPSTR * pDbcsString
|
|
);
|
|
|
|
//
|
|
// rplmain.c
|
|
//
|
|
|
|
VOID RPL_main(
|
|
IN DWORD argc,
|
|
IN LPWSTR argv[]
|
|
);
|
|
VOID RplInitError(
|
|
DWORD ErrorCode,
|
|
PCHAR ErrorIdString
|
|
);
|
|
BOOL RplServiceAttemptStop( VOID);
|
|
DWORD RplUpdateStatus( VOID);
|
|
|
|
|
|
//
|
|
// Declare/Define all global variables.
|
|
//
|
|
|
|
#include "rpldata.h" // defines/declares global data structures
|