/*++ 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 // ntexapi.h\NtQuerySystemTime #include // RtlTimeToSecondsSince1970 #include #include // DWORD, IN, File APIs, etc. #include #include #include // vsprintf #include // isspace #include // NERR_RplBootStartFailed - used to be here #include // NetApiBufferFree #include #include #include // STD_ALERT ALERT_OTHER_INFO #include #include #include #include #include // Lock data types, functions, and macros. #include // FORMAT_NET_THREAD_ID, NetpCurrentThread(). #include // PSHARE_INFO_2 #include // NetGroupGetInfo #include // NetConfigGet #include // NCB // // Global types and constants (used in all RPL server files). // #include // includes __JET500 flag #include #include #include // rplnet.dll entry points & return codes #include // AddKey(), MapJetError(), FillTcpIpString() #include #include // DataTypes and runtime APIs #include // 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 // 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(' '); ; db 0dh ; db 0ah ; db '$' ; 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