mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 23:33:01 +00:00
Sync with trunk.
svn path=/branches/ntvdm/; revision=59679
This commit is contained in:
commit
ed55d73cfd
47 changed files with 12143 additions and 4422 deletions
|
@ -22,7 +22,7 @@ BEGIN
|
|||
MENUITEM SEPARATOR
|
||||
MENUITEM "刷新(&R)", ID_REFRESH
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Update Da&tabase", ID_RESETDB
|
||||
MENUITEM "更新数据库(&A)", ID_RESETDB
|
||||
END
|
||||
POPUP "帮助"
|
||||
BEGIN
|
||||
|
@ -52,7 +52,7 @@ BEGIN
|
|||
MENUITEM SEPARATOR
|
||||
MENUITEM "刷新(&R)", ID_REFRESH
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Update Da&tabase", ID_RESETDB
|
||||
MENUITEM "更新数据库(&A)", ID_RESETDB
|
||||
END
|
||||
END
|
||||
|
||||
|
|
202
base/applications/rapps/lang/zh-TW.rc
Normal file
202
base/applications/rapps/lang/zh-TW.rc
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Translated by Song Fuchang (0xfc) <sfc_0@yahoo.com.cn>
|
||||
* Converted by OpenCC 0.4.2 <opencc.googlecode.com>
|
||||
*/
|
||||
|
||||
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
|
||||
|
||||
IDR_MAINMENU MENU
|
||||
BEGIN
|
||||
POPUP "檔案(&F)"
|
||||
BEGIN
|
||||
MENUITEM "設定(&S)", ID_SETTINGS
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "退出(&X)", ID_EXIT
|
||||
END
|
||||
POPUP "程式(&P)"
|
||||
BEGIN
|
||||
MENUITEM "安裝(&I)", ID_INSTALL
|
||||
MENUITEM "解除安裝(&U)", ID_UNINSTALL
|
||||
MENUITEM "修改(&M)", ID_MODIFY
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "從登錄檔刪除(&E)", ID_REGREMOVE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "重新整理(&R)", ID_REFRESH
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "更新資料庫(&A)", ID_RESETDB
|
||||
END
|
||||
POPUP "幫助"
|
||||
BEGIN
|
||||
MENUITEM "幫助內容", ID_HELP, GRAYED
|
||||
MENUITEM "關於", ID_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
IDR_LINKMENU MENU
|
||||
BEGIN
|
||||
POPUP "popup"
|
||||
BEGIN
|
||||
MENUITEM "在瀏覽器中開啟連結(&O)", ID_OPEN_LINK
|
||||
MENUITEM "複製連結到剪貼簿(&C)", ID_COPY_LINK
|
||||
END
|
||||
END
|
||||
|
||||
IDR_APPLICATIONMENU MENU
|
||||
BEGIN
|
||||
POPUP "popup"
|
||||
BEGIN
|
||||
MENUITEM "安裝(&I)", ID_INSTALL
|
||||
MENUITEM "解除安裝(&U)", ID_UNINSTALL
|
||||
MENUITEM "修改(&M)", ID_MODIFY
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "從登錄檔刪除(&E)", ID_REGREMOVE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "重新整理(&R)", ID_REFRESH
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "更新資料庫(&A)", ID_RESETDB
|
||||
END
|
||||
END
|
||||
|
||||
IDD_SETTINGS_DIALOG DIALOGEX DISCARDABLE 0, 0, 250, 144
|
||||
STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "設定"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
GROUPBOX "普通", -1, 4, 2, 240, 61
|
||||
AUTOCHECKBOX "儲存視窗位置(&S)", IDC_SAVE_WINDOW_POS, 15, 12, 219, 12
|
||||
AUTOCHECKBOX "啟動時更新可獲得的程式列表(&U)", IDC_UPDATE_AVLIST, 15, 29, 222, 12
|
||||
AUTOCHECKBOX "將程式的安裝和解除安裝記錄到日誌(&L)", IDC_LOG_ENABLED, 15, 46, 219, 12
|
||||
|
||||
GROUPBOX "正在下載", -1, 4, 65, 240, 51
|
||||
LTEXT "下載資料夾:", -1, 16, 75, 100, 9
|
||||
EDITTEXT IDC_DOWNLOAD_DIR_EDIT, 15, 86, 166, 12, WS_CHILD | WS_VISIBLE | WS_GROUP
|
||||
PUSHBUTTON "選擇(&C)", IDC_CHOOSE, 187, 85, 50, 14
|
||||
AUTOCHECKBOX "在安裝完程式後刪除安裝程式(&D)", IDC_DEL_AFTER_INSTALL, 16, 100, 218, 12
|
||||
|
||||
PUSHBUTTON "預設", IDC_DEFAULT_SETTINGS, 8, 124, 60, 14
|
||||
PUSHBUTTON "確定", IDOK, 116, 124, 60, 14
|
||||
PUSHBUTTON "取消", IDCANCEL, 181, 124, 60, 14
|
||||
END
|
||||
|
||||
IDD_INSTALL_DIALOG DIALOGEX DISCARDABLE 0, 0, 216, 97
|
||||
STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "安裝程式"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "...", IDC_INSTALL_TEXT, 4, 5, 209, 35
|
||||
|
||||
AUTORADIOBUTTON "從存儲裝置安裝 (CD 或 DVD)(&I)", IDC_CD_INSTALL, 10, 46, 197, 11, WS_GROUP
|
||||
AUTORADIOBUTTON "下載並安裝(&D)", IDC_DOWNLOAD_INSTALL, 10, 59, 197, 11, NOT WS_TABSTOP
|
||||
|
||||
PUSHBUTTON "確定", IDOK, 86, 78, 60, 14
|
||||
PUSHBUTTON "取消", IDCANCEL, 150, 78, 60, 14
|
||||
END
|
||||
|
||||
IDD_DOWNLOAD_DIALOG DIALOGEX LOADONCALL MOVEABLE DISCARDABLE 0, 0, 220, 76
|
||||
STYLE DS_SHELLFONT | DS_CENTER | WS_BORDER | WS_CAPTION | WS_POPUP | WS_SYSMENU | WS_VISIBLE
|
||||
CAPTION "正在下載..."
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
CONTROL "Progress1", IDC_DOWNLOAD_PROGRESS, "msctls_progress32", WS_BORDER | PBS_SMOOTH, 10, 10, 200, 12
|
||||
LTEXT "", IDC_DOWNLOAD_STATUS, 10, 30, 200, 10, SS_CENTER
|
||||
PUSHBUTTON "取消", IDCANCEL, 85, 58, 50, 15, WS_GROUP | WS_TABSTOP
|
||||
END
|
||||
|
||||
IDD_ABOUT_DIALOG DIALOGEX 22, 16, 190, 66
|
||||
STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME
|
||||
CAPTION "關於"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
BEGIN
|
||||
LTEXT "ReactOS 程式管理器 版權所有 (C) 2009\n作者 Dmitry Chapyshev (dmitry@reactos.org)", IDC_STATIC, 48, 7, 130, 39
|
||||
PUSHBUTTON "關閉", IDOK, 133, 46, 50, 14
|
||||
ICON IDI_MAIN, IDC_STATIC, 10, 10, 7, 30
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_TOOLTIP_INSTALL "安裝"
|
||||
IDS_TOOLTIP_UNINSTALL "解除安裝"
|
||||
IDS_TOOLTIP_MODIFY "修改"
|
||||
IDS_TOOLTIP_SETTINGS "設定"
|
||||
IDS_TOOLTIP_REFRESH "重新整理"
|
||||
IDS_TOOLTIP_EXIT "退出"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_APP_NAME "名稱"
|
||||
IDS_APP_INST_VERSION "版本"
|
||||
IDS_APP_DESCRIPTION "描述"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_INFO_VERSION "版本:"
|
||||
IDS_INFO_DESCRIPTION "描述:"
|
||||
IDS_INFO_PUBLISHER "\n釋出者:"
|
||||
IDS_INFO_HELPLINK "\n幫助連結:"
|
||||
IDS_INFO_HELPPHONE "\n幫助電話:"
|
||||
IDS_INFO_README "\n必讀:"
|
||||
IDS_INFO_REGOWNER "\n註冊所有者:"
|
||||
IDS_INFO_PRODUCTID "\n產品 ID:"
|
||||
IDS_INFO_CONTACT "\n聯繫方式:"
|
||||
IDS_INFO_UPDATEINFO "\n更新資訊:"
|
||||
IDS_INFO_INFOABOUT "\n關於資訊:"
|
||||
IDS_INFO_COMMENTS "\n註釋:"
|
||||
IDS_INFO_INSTLOCATION "\n安裝位置:"
|
||||
IDS_INFO_INSTALLSRC "\n安裝源:"
|
||||
IDS_INFO_UNINSTALLSTR "\n解除安裝字元串:"
|
||||
IDS_INFO_MODIFYPATH "\n修改路徑:"
|
||||
IDS_INFO_INSTALLDATE "\n安裝日期:"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_AINFO_VERSION "\n版本:"
|
||||
IDS_AINFO_DESCRIPTION "\n描述:"
|
||||
IDS_AINFO_SIZE "\n大小:"
|
||||
IDS_AINFO_URLSITE "\n主頁:"
|
||||
IDS_AINFO_LICENCE "\n協議:"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_CAT_AUDIO "音訊"
|
||||
IDS_CAT_DEVEL "開發"
|
||||
IDS_CAT_DRIVERS "驅動程式"
|
||||
IDS_CAT_EDU "教育與娛樂"
|
||||
IDS_CAT_ENGINEER "工程"
|
||||
IDS_CAT_FINANCE "經濟"
|
||||
IDS_CAT_GAMES "遊戲與娛樂"
|
||||
IDS_CAT_GRAPHICS "圖形"
|
||||
IDS_CAT_INTERNET "Internet 與網路"
|
||||
IDS_CAT_LIBS "庫"
|
||||
IDS_CAT_OFFICE "辦公"
|
||||
IDS_CAT_OTHER "其他"
|
||||
IDS_CAT_SCIENCE "科學"
|
||||
IDS_CAT_TOOLS "工具"
|
||||
IDS_CAT_VIDEO "視訊"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_APPTITLE "ReactOS 程式管理器"
|
||||
IDS_SEARCH_TEXT "搜索..."
|
||||
IDS_INSTALL "安裝"
|
||||
IDS_UNINSTALL "解除安裝"
|
||||
IDS_MODIFY "修改"
|
||||
IDS_APPS_COUNT "程式個數:%d"
|
||||
IDS_WELCOME_TITLE "歡迎來到 ReactOS 程式管理器!\n\n"
|
||||
IDS_WELCOME_TEXT "從左欄選擇一個類別,然後選擇要安裝或解除安裝的程式。\nReactOS 網站:"
|
||||
IDS_WELCOME_URL "http://www.reactos.org"
|
||||
IDS_INSTALLED "已安裝"
|
||||
IDS_AVAILABLEFORINST "可安裝"
|
||||
IDS_UPDATES "更新"
|
||||
IDS_APPLICATIONS "應用程式"
|
||||
IDS_CHOOSE_FOLDER_TEXT "請選擇用來儲存下載檔案的資料夾:"
|
||||
IDS_CHOOSE_FOLDER_ERROR "您選擇的資料夾不存在。創建嗎?"
|
||||
IDS_USER_NOT_ADMIN "您必須以管理員許可權啟動 ""ReactOS 程式管理器""!"
|
||||
IDS_APP_REG_REMOVE "您確定要從登錄檔刪除該程式的資料嗎?"
|
||||
IDS_INFORMATION "資訊"
|
||||
IDS_UNABLE_TO_REMOVE "無法從登錄檔刪除該程式的資料!"
|
||||
END
|
|
@ -7,7 +7,7 @@ Licence = GPL
|
|||
Description = A media player.
|
||||
Size = 7.08MB
|
||||
Category = 1
|
||||
URLSite = http://mpc-hc.sourceforge.net/
|
||||
URLSite = http://mpc-hc.org/
|
||||
URLDownload = http://garr.dl.sourceforge.net/project/mpc-hc/MPC%20HomeCinema%20-%20Win32/MPC-HC_v1.6.8_x86/MPC-HC.1.6.8.x86.exe
|
||||
CDPath = none
|
||||
|
||||
|
|
|
@ -56,3 +56,6 @@
|
|||
#ifdef LANGUAGE_ZH_CN
|
||||
#include "lang/zh-CN.rc"
|
||||
#endif
|
||||
#ifdef LANGUAGE_ZH_TW
|
||||
#include "lang/zh-TW.rc"
|
||||
#endif
|
||||
|
|
|
@ -1149,6 +1149,8 @@ HKLM,"SYSTEM\CurrentControlSet\Control\SecurityProviders\SaslProfiles",,0x000000
|
|||
|
||||
; Service groups
|
||||
HKLM,"SYSTEM\CurrentControlSet\Control\ServiceGroupOrder","List",0x00010000, \
|
||||
"System Reserved", \
|
||||
"EMS", \
|
||||
"Boot Bus Extender", \
|
||||
"System Bus Extender", \
|
||||
"SCSI Miniport", \
|
||||
|
@ -1342,6 +1344,13 @@ HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Start",0x00010001,0x00000002
|
|||
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Type",0x00010001,0x00000020
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\dhcpcsvc.dll"
|
||||
|
||||
; EMS Serial Administration Console Driver
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","ErrorControl",0x00010001,0x00000000
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Group",0x00000000,"EMS"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","ImagePath",0x00020000,"system32\drivers\sacdrv.sys"
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Start",0x00010001,0x00000000
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\NMIDebug","Type",0x00010001,0x00000001
|
||||
|
||||
; Event logging service
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\EventLog",,0x00000010
|
||||
HKLM,"SYSTEM\CurrentControlSet\Services\EventLog","DisplayName",0x00000000,"Event Logger"
|
||||
|
|
|
@ -18,6 +18,7 @@ FreeSysPartDiskSpace=350
|
|||
[SourceDisksFiles]
|
||||
acpi.sys=,,,,,,,,,,,,4
|
||||
nmidebug.sys=,,,,,,x,,,,,,4
|
||||
sacdrv.sys=,,,,,,x,,,,,,4
|
||||
uniata.sys=,,,,,,x,,,,,,4
|
||||
buslogic.sys=,,,,,,x,,,,,,4
|
||||
blue.sys=,,,,,,x,,,,,,4
|
||||
|
|
|
@ -1,307 +0,0 @@
|
|||
# try to load any previously computed information for C on this platform
|
||||
INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake OPTIONAL)
|
||||
# try to load any previously computed information for CXX on this platform
|
||||
INCLUDE( ${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake OPTIONAL)
|
||||
|
||||
SET(WIN32 1)
|
||||
|
||||
INCLUDE(Platform/cl)
|
||||
|
||||
############
|
||||
# Detect WDK build environment
|
||||
IF($ENV{DDKBUILDENV} MATCHES "chk")
|
||||
MESSAGE(STATUS "DDK/WDK checked build environment detected.")
|
||||
SET(CMAKE_USE_WDK_ENV 1)
|
||||
ENDIF()
|
||||
|
||||
IF($ENV{DDKBUILDENV} MATCHES "fre")
|
||||
MESSAGE(STATUS "DDK/WDK free build environment detected.")
|
||||
SET(CMAKE_USE_WDK_ENV 1)
|
||||
ENDIF()
|
||||
|
||||
if(CMAKE_USE_WDK_ENV)
|
||||
|
||||
# Detect output architecture
|
||||
if(NOT ARCH)
|
||||
if($ENV{AMD64} MATCHES 1)
|
||||
set(ARCH amd64)
|
||||
set(MSVC_C_ARCHITECTURE_ID 64)
|
||||
else()
|
||||
set(ARCH i386)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Force C/C++ Compilers
|
||||
include(CMakeForceCompiler)
|
||||
CMAKE_FORCE_C_COMPILER(cl MSVC)
|
||||
CMAKE_FORCE_CXX_COMPILER(cl MSVC)
|
||||
|
||||
# Add library directories
|
||||
STRING(REPLACE * ${ARCH} ATL_LIB_PATH $ENV{ATL_LIB_PATH})
|
||||
STRING(REPLACE * ${ARCH} CRT_LIB_PATH $ENV{CRT_LIB_PATH})
|
||||
STRING(REPLACE * ${ARCH} DDK_LIB_PATH $ENV{DDK_LIB_PATH})
|
||||
STRING(REPLACE * ${ARCH} KMDF_LIB_PATH $ENV{KMDF_LIB_PATH})
|
||||
STRING(REPLACE * ${ARCH} MFC_LIB_PATH $ENV{MFC_LIB_PATH})
|
||||
STRING(REPLACE * ${ARCH} SDK_LIB_PATH $ENV{SDK_LIB_PATH})
|
||||
LINK_DIRECTORIES(${ATL_LIB_PATH}
|
||||
${CRT_LIB_PATH}
|
||||
${DDK_LIB_PATH}
|
||||
${IFSKIT_LIB_PATH}
|
||||
${KMDF_LIB_PATH}
|
||||
${MFC_LIB_PATH}
|
||||
${SDK_LIB_PATH})
|
||||
|
||||
# Add environment variables
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
set(ENV{INCLUDE} "$ENV{CRT_INC_PATH};$ENV{SDK_INC_PATH};$ENV{SDK_INC_PATH}\\crt\\stl60")
|
||||
include_directories($ENV{INCLUDE})
|
||||
set(ENV{LIBPATH} "${CRT_LIB_PATH};${SDK_LIB_PATH}")
|
||||
set(ENV{USE_MSVCRT} 1)
|
||||
set(ENV{USE_STL} 1)
|
||||
set(ENV{STL_VER} 60)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
############
|
||||
|
||||
# Set lib path for ARM compiler
|
||||
if(${ARCH} MATCHES arm)
|
||||
message("Using ARM build for cross compilation. Host tools are x86.")
|
||||
|
||||
# Force C/C++ Compilers
|
||||
include(CMakeForceCompiler)
|
||||
CMAKE_FORCE_C_COMPILER(cl MSVC)
|
||||
CMAKE_FORCE_CXX_COMPILER(cl MSVC)
|
||||
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
message("Using x86 target for ARM host tools.")
|
||||
set(ARCH i386)
|
||||
|
||||
LINK_DIRECTORIES($ENV{WindowsSdkDir}\\Lib\\win8\\um\\x86)
|
||||
endif()
|
||||
|
||||
#LINK_DIRECTORIES($ENV{LIB})
|
||||
endif()
|
||||
|
||||
|
||||
############
|
||||
|
||||
SET(CMAKE_CREATE_WIN32_EXE /subsystem:windows)
|
||||
SET(CMAKE_CREATE_CONSOLE_EXE /subsystem:console)
|
||||
|
||||
IF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
|
||||
SET (CMAKE_NO_BUILD_TYPE 1)
|
||||
ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 6")
|
||||
IF(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
SET (CMAKE_NO_BUILD_TYPE 1)
|
||||
SET (CMAKE_CONFIGURATION_TYPES "Debug;Release;MinSizeRel;RelWithDebInfo" CACHE STRING
|
||||
"Semicolon separated list of supported configuration types, only supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything else will be ignored.")
|
||||
MARK_AS_ADVANCED(CMAKE_CONFIGURATION_TYPES)
|
||||
ENDIF(NOT CMAKE_NO_BUILD_TYPE AND CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
# does the compiler support pdbtype and is it the newer compiler
|
||||
IF(CMAKE_GENERATOR MATCHES "Visual Studio 8")
|
||||
SET(CMAKE_COMPILER_2005 1)
|
||||
ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8")
|
||||
|
||||
# make sure to enable languages after setting configuration types
|
||||
ENABLE_LANGUAGE(RC)
|
||||
SET(CMAKE_COMPILE_RESOURCE "rc <FLAGS> /fo<OBJECT> <SOURCE>")
|
||||
|
||||
# for nmake we need to compute some information about the compiler
|
||||
# that is being used.
|
||||
# the compiler may be free command line, 6, 7, or 71, and
|
||||
# each have properties that must be determined.
|
||||
# to avoid running these tests with each cmake run, the
|
||||
# test results are saved in CMakeCPlatform.cmake, a file
|
||||
# that is automatically copied into try_compile directories
|
||||
# by the global generator.
|
||||
SET(MSVC_IDE 1)
|
||||
IF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
|
||||
SET(MSVC_IDE 0)
|
||||
IF(NOT CMAKE_VC_COMPILER_TESTS_RUN)
|
||||
SET(CMAKE_VC_COMPILER_TESTS 1)
|
||||
SET(testNmakeCLVersionFile
|
||||
"${CMAKE_ROOT}/Modules/CMakeTestNMakeCLVersion.c")
|
||||
STRING(REGEX REPLACE "/" "\\\\" testNmakeCLVersionFile "${testNmakeCLVersionFile}")
|
||||
MESSAGE(STATUS "Check for CL compiler version")
|
||||
SET(CMAKE_TEST_COMPILER ${CMAKE_C_COMPILER})
|
||||
IF (NOT CMAKE_C_COMPILER)
|
||||
SET(CMAKE_TEST_COMPILER ${CMAKE_CXX_COMPILER})
|
||||
ENDIF(NOT CMAKE_C_COMPILER)
|
||||
EXEC_PROGRAM(${CMAKE_TEST_COMPILER}
|
||||
ARGS /nologo -EP \"${testNmakeCLVersionFile}\"
|
||||
OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT
|
||||
RETURN_VALUE CMAKE_COMPILER_RETURN
|
||||
)
|
||||
IF(NOT CMAKE_COMPILER_RETURN)
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Determining the version of compiler passed with the following output:\n"
|
||||
"${CMAKE_COMPILER_OUTPUT}\n\n")
|
||||
STRING(REGEX REPLACE "\n" " " compilerVersion "${CMAKE_COMPILER_OUTPUT}")
|
||||
STRING(REGEX REPLACE ".*VERSION=(.*)" "\\1"
|
||||
compilerVersion "${compilerVersion}")
|
||||
MESSAGE(STATUS "Check for CL compiler version - ${compilerVersion}")
|
||||
SET(MSVC60)
|
||||
SET(MSVC70)
|
||||
SET(MSVC71)
|
||||
SET(MSVC80)
|
||||
SET(CMAKE_COMPILER_2005)
|
||||
IF("${compilerVersion}" LESS 1300)
|
||||
SET(MSVC60 1)
|
||||
SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 1)
|
||||
ENDIF("${compilerVersion}" LESS 1300)
|
||||
IF("${compilerVersion}" EQUAL 1300)
|
||||
SET(MSVC70 1)
|
||||
SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 0)
|
||||
ENDIF("${compilerVersion}" EQUAL 1300)
|
||||
IF("${compilerVersion}" EQUAL 1310)
|
||||
SET(MSVC71 1)
|
||||
SET(CMAKE_COMPILER_SUPPORTS_PDBTYPE 0)
|
||||
ENDIF("${compilerVersion}" EQUAL 1310)
|
||||
IF("${compilerVersion}" EQUAL 1400)
|
||||
SET(MSVC80 1)
|
||||
SET(CMAKE_COMPILER_2005 1)
|
||||
ENDIF("${compilerVersion}" EQUAL 1400)
|
||||
IF("${compilerVersion}" EQUAL 1500)
|
||||
SET(MSVC90 1)
|
||||
ENDIF("${compilerVersion}" EQUAL 1500)
|
||||
IF("${compilerVersion}" EQUAL 1600)
|
||||
SET(MSVC10 1)
|
||||
ENDIF("${compilerVersion}" EQUAL 1600)
|
||||
SET(MSVC_VERSION "${compilerVersion}")
|
||||
ELSE(NOT CMAKE_COMPILER_RETURN)
|
||||
MESSAGE(STATUS "Check for CL compiler version - failed")
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Determining the version of compiler failed with the following output:\n"
|
||||
"${CMAKE_COMPILER_OUTPUT}\n\n")
|
||||
ENDIF(NOT CMAKE_COMPILER_RETURN)
|
||||
# try to figure out if we are running the free command line
|
||||
# tools from Microsoft. These tools do not provide debug libraries,
|
||||
# so the link flags used have to be different.
|
||||
MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2")
|
||||
SET(testForFreeVCFile
|
||||
"${CMAKE_ROOT}/Modules/CMakeTestForFreeVC.cxx")
|
||||
STRING(REGEX REPLACE "/" "\\\\" testForFreeVCFile "${testForFreeVCFile}")
|
||||
MESSAGE(STATUS "Check if this is a free VC compiler")
|
||||
EXEC_PROGRAM(${CMAKE_TEST_COMPILER} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp2
|
||||
ARGS /nologo /EHsc
|
||||
\"${testForFreeVCFile}\"
|
||||
OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT
|
||||
RETURN_VALUE CMAKE_COMPILER_RETURN
|
||||
)
|
||||
IF(CMAKE_COMPILER_RETURN)
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Determining if this is a free VC compiler failed with the following output:\n"
|
||||
"${CMAKE_COMPILER_OUTPUT}\n\n")
|
||||
MESSAGE(STATUS "Check if this is a free VC compiler - yes")
|
||||
SET(CMAKE_USING_VC_FREE_TOOLS 1)
|
||||
ELSE(CMAKE_COMPILER_RETURN)
|
||||
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Determining if this is a free VC compiler passed with the following output:\n"
|
||||
"${CMAKE_COMPILER_OUTPUT}\n\n")
|
||||
MESSAGE(STATUS "Check if this is a free VC compiler - no")
|
||||
SET(CMAKE_USING_VC_FREE_TOOLS 0)
|
||||
ENDIF(CMAKE_COMPILER_RETURN)
|
||||
MAKE_DIRECTORY("${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp3")
|
||||
ENDIF(NOT CMAKE_VC_COMPILER_TESTS_RUN)
|
||||
ENDIF(CMAKE_GENERATOR MATCHES "Makefiles" OR CMAKE_GENERATOR MATCHES "Ninja")
|
||||
|
||||
IF(MSVC_C_ARCHITECTURE_ID MATCHES 64)
|
||||
SET(CMAKE_CL_64 1)
|
||||
ELSE(MSVC_C_ARCHITECTURE_ID MATCHES 64)
|
||||
SET(CMAKE_CL_64 0)
|
||||
ENDIF(MSVC_C_ARCHITECTURE_ID MATCHES 64)
|
||||
IF(CMAKE_FORCE_WIN64 OR CMAKE_FORCE_IA64)
|
||||
SET(CMAKE_CL_64 1)
|
||||
ENDIF(CMAKE_FORCE_WIN64 OR CMAKE_FORCE_IA64)
|
||||
|
||||
IF("${MSVC_VERSION}" GREATER 1599)
|
||||
SET(MSVC_INCREMENTAL_DEFAULT ON)
|
||||
ENDIF()
|
||||
|
||||
# No support for old versions
|
||||
if(MSVC_VERSION LESS 1310)
|
||||
message(FATAL_ERROR "Your compiler is too old. Get a newer version!")
|
||||
endif()
|
||||
|
||||
# for 2005 make sure the manifest is put in the dll with mt
|
||||
#SET(CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_COMMAND> -E vs_link_dll ${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
|
||||
#SET(CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_COMMAND> -E vs_link_dll ${CMAKE_CXX_CREATE_SHARED_MODULE}")
|
||||
# create a C shared library
|
||||
#SET(CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
|
||||
# create a C shared module just copy the shared library rule
|
||||
#SET(CMAKE_C_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_MODULE}")
|
||||
#SET(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_COMMAND> -E vs_link_exe ${CMAKE_CXX_LINK_EXECUTABLE}")
|
||||
#SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_COMMAND> -E vs_link_exe ${CMAKE_C_LINK_EXECUTABLE}")
|
||||
|
||||
SET(CMAKE_BUILD_TYPE_INIT Debug)
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG_INIT "")
|
||||
SET(CMAKE_C_FLAGS_DEBUG_INIT "")
|
||||
SET(CMAKE_CXX_FLAGS_INIT "")
|
||||
SET(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/O1 /Ob1 /D NDEBUG")
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE_INIT "")
|
||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/Zi /O2 /Ob1")
|
||||
SET(CMAKE_C_FLAGS_INIT "")
|
||||
SET(CMAKE_C_FLAGS_MINSIZEREL_INIT "/O1 /Ob1 /D NDEBUG")
|
||||
SET(CMAKE_C_FLAGS_RELEASE_INIT "")
|
||||
SET(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/Zi /O2 /Ob1")
|
||||
SET(CMAKE_C_STANDARD_LIBRARIES_INIT "")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_INIT "${CMAKE_EXE_LINKER_FLAGS_INIT}")
|
||||
SET(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
|
||||
|
||||
# executable linker flags
|
||||
SET (CMAKE_LINK_DEF_FILE_FLAG "/DEF:")
|
||||
# set the stack size and the machine type
|
||||
SET(_MACHINE_ARCH_FLAG ${MSVC_C_ARCHITECTURE_ID})
|
||||
IF(NOT _MACHINE_ARCH_FLAG)
|
||||
SET(_MACHINE_ARCH_FLAG ${MSVC_CXX_ARCHITECTURE_ID})
|
||||
ENDIF(NOT _MACHINE_ARCH_FLAG)
|
||||
# HACK
|
||||
if(${ARCH} MATCHES arm)
|
||||
SET(_MACHINE_ARCH_FLAG ARM)
|
||||
endif()
|
||||
SET (CMAKE_EXE_LINKER_FLAGS_INIT
|
||||
"${CMAKE_EXE_LINKER_FLAGS_INIT} /STACK:10000000 /machine:${_MACHINE_ARCH_FLAG}")
|
||||
|
||||
# add /debug and /INCREMENTAL:YES to DEBUG and RELWITHDEBINFO also add pdbtype
|
||||
# on versions that support it
|
||||
SET( MSVC_INCREMENTAL_YES_FLAG "")
|
||||
IF(NOT MSVC_INCREMENTAL_DEFAULT)
|
||||
SET( MSVC_INCREMENTAL_YES_FLAG "/INCREMENTAL:YES")
|
||||
ENDIF()
|
||||
|
||||
IF (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
|
||||
SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug /pdbtype:sept ${MSVC_INCREMENTAL_YES_FLAG}")
|
||||
SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug /pdbtype:sept ${MSVC_INCREMENTAL_YES_FLAG}")
|
||||
ELSE (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
|
||||
SET (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug ${MSVC_INCREMENTAL_YES_FLAG}")
|
||||
SET (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug ${MSVC_INCREMENTAL_YES_FLAG}")
|
||||
ENDIF (CMAKE_COMPILER_SUPPORTS_PDBTYPE)
|
||||
# for release and minsize release default to no incremental linking
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT "/INCREMENTAL:NO")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT "/INCREMENTAL:NO")
|
||||
|
||||
# copy the EXE_LINKER flags to SHARED and MODULE linker flags
|
||||
# shared linker flags
|
||||
SET (CMAKE_SHARED_LINKER_FLAGS_INIT ${CMAKE_EXE_LINKER_FLAGS_INIT})
|
||||
SET (CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT})
|
||||
SET (CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT})
|
||||
SET (CMAKE_SHARED_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT})
|
||||
SET (CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT})
|
||||
# module linker flags
|
||||
SET (CMAKE_MODULE_LINKER_FLAGS_INIT ${CMAKE_SHARED_LINKER_FLAGS_INIT})
|
||||
SET (CMAKE_MODULE_LINKER_FLAGS_DEBUG_INIT ${CMAKE_SHARED_LINKER_FLAGS_DEBUG_INIT})
|
||||
SET (CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO_INIT ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT})
|
||||
SET (CMAKE_MODULE_LINKER_FLAGS_RELEASE_INIT ${CMAKE_EXE_LINKER_FLAGS_RELEASE_INIT})
|
||||
SET (CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL_INIT ${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL_INIT})
|
||||
|
||||
# save computed information for this platform
|
||||
IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake")
|
||||
CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCPlatform.cmake IMMEDIATE)
|
||||
ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCPlatform.cmake")
|
||||
|
||||
IF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake")
|
||||
CONFIGURE_FILE(${CMAKE_ROOT}/Modules/Platform/Windows-cl.cmake.in
|
||||
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeCXXPlatform.cmake IMMEDIATE)
|
||||
ENDIF(NOT EXISTS "${CMAKE_PLATFORM_ROOT_BIN}/CMakeCXXPlatform.cmake")
|
|
@ -47,6 +47,7 @@ list(APPEND SOURCE
|
|||
client/file/delete.c
|
||||
client/file/deviceio.c
|
||||
client/file/dir.c
|
||||
client/file/disk.c
|
||||
client/file/fileinfo.c
|
||||
client/file/filemap.c
|
||||
client/file/filename.c
|
||||
|
@ -57,6 +58,7 @@ list(APPEND SOURCE
|
|||
client/file/lock.c
|
||||
client/file/mailslot.c
|
||||
client/file/move.c
|
||||
client/file/mntpoint.c
|
||||
client/file/npipe.c
|
||||
client/file/rw.c
|
||||
client/file/tape.c
|
||||
|
|
424
dll/win32/kernel32/client/file/disk.c
Normal file
424
dll/win32/kernel32/client/file/disk.c
Normal file
|
@ -0,0 +1,424 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/file/disk.c
|
||||
* PURPOSE: Disk and Drive functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* Erik Bos, Alexandre Julliard :
|
||||
* GetLogicalDriveStringsA,
|
||||
* GetLogicalDriveStringsW, GetLogicalDrives
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
//WINE copyright notice:
|
||||
/*
|
||||
* DOS drives handling functions
|
||||
*
|
||||
* Copyright 1993 Erik Bos
|
||||
* Copyright 1996 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include <k32.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
DEBUG_CHANNEL(kernel32file);
|
||||
|
||||
#define MAX_DOS_DRIVES 26
|
||||
HANDLE WINAPI InternalOpenDirW(IN LPCWSTR DirName, IN BOOLEAN Write);
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
/* Synced to Wine-2008/12/28 */
|
||||
DWORD
|
||||
WINAPI
|
||||
GetLogicalDriveStringsA(IN DWORD nBufferLength,
|
||||
IN LPSTR lpBuffer)
|
||||
{
|
||||
DWORD drive, count;
|
||||
DWORD dwDriveMap;
|
||||
LPSTR p;
|
||||
|
||||
dwDriveMap = GetLogicalDrives();
|
||||
|
||||
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||
{
|
||||
if (dwDriveMap & (1<<drive))
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
if ((count * 4) + 1 > nBufferLength) return ((count * 4) + 1);
|
||||
|
||||
p = lpBuffer;
|
||||
|
||||
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||
if (dwDriveMap & (1<<drive))
|
||||
{
|
||||
*p++ = 'A' + (UCHAR)drive;
|
||||
*p++ = ':';
|
||||
*p++ = '\\';
|
||||
*p++ = '\0';
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
return (count * 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
/* Synced to Wine-2008/12/28 */
|
||||
DWORD
|
||||
WINAPI
|
||||
GetLogicalDriveStringsW(IN DWORD nBufferLength,
|
||||
IN LPWSTR lpBuffer)
|
||||
{
|
||||
DWORD drive, count;
|
||||
DWORD dwDriveMap;
|
||||
LPWSTR p;
|
||||
|
||||
dwDriveMap = GetLogicalDrives();
|
||||
|
||||
for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||
{
|
||||
if (dwDriveMap & (1<<drive))
|
||||
count++;
|
||||
}
|
||||
|
||||
if ((count * 4) + 1 > nBufferLength) return ((count * 4) + 1);
|
||||
|
||||
p = lpBuffer;
|
||||
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||
if (dwDriveMap & (1<<drive))
|
||||
{
|
||||
*p++ = (WCHAR)('A' + drive);
|
||||
*p++ = (WCHAR)':';
|
||||
*p++ = (WCHAR)'\\';
|
||||
*p++ = (WCHAR)'\0';
|
||||
}
|
||||
*p = (WCHAR)'\0';
|
||||
|
||||
return (count * 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
/* Synced to Wine-? */
|
||||
DWORD
|
||||
WINAPI
|
||||
GetLogicalDrives(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PROCESS_DEVICEMAP_INFORMATION ProcessDeviceMapInfo;
|
||||
|
||||
/* Get the Device Map for this Process */
|
||||
Status = NtQueryInformationProcess(NtCurrentProcess(),
|
||||
ProcessDeviceMap,
|
||||
&ProcessDeviceMapInfo,
|
||||
sizeof(ProcessDeviceMapInfo),
|
||||
NULL);
|
||||
|
||||
/* Return the Drive Map */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ProcessDeviceMapInfo.Query.DriveMap;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetDiskFreeSpaceA(IN LPCSTR lpRootPathName,
|
||||
OUT LPDWORD lpSectorsPerCluster,
|
||||
OUT LPDWORD lpBytesPerSector,
|
||||
OUT LPDWORD lpNumberOfFreeClusters,
|
||||
OUT LPDWORD lpTotalNumberOfClusters)
|
||||
{
|
||||
PWCHAR RootPathNameW=NULL;
|
||||
|
||||
if (lpRootPathName)
|
||||
{
|
||||
if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return GetDiskFreeSpaceW (RootPathNameW,
|
||||
lpSectorsPerCluster,
|
||||
lpBytesPerSector,
|
||||
lpNumberOfFreeClusters,
|
||||
lpTotalNumberOfClusters);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetDiskFreeSpaceW(IN LPCWSTR lpRootPathName,
|
||||
OUT LPDWORD lpSectorsPerCluster,
|
||||
OUT LPDWORD lpBytesPerSector,
|
||||
OUT LPDWORD lpNumberOfFreeClusters,
|
||||
OUT LPDWORD lpTotalNumberOfClusters)
|
||||
{
|
||||
FILE_FS_SIZE_INFORMATION FileFsSize;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
WCHAR RootPathName[MAX_PATH];
|
||||
HANDLE hFile;
|
||||
NTSTATUS errCode;
|
||||
|
||||
if (lpRootPathName)
|
||||
{
|
||||
wcsncpy (RootPathName, lpRootPathName, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetCurrentDirectoryW (MAX_PATH, RootPathName);
|
||||
}
|
||||
RootPathName[3] = 0;
|
||||
|
||||
hFile = InternalOpenDirW(RootPathName, FALSE);
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
{
|
||||
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
errCode = NtQueryVolumeInformationFile(hFile,
|
||||
&IoStatusBlock,
|
||||
&FileFsSize,
|
||||
sizeof(FILE_FS_SIZE_INFORMATION),
|
||||
FileFsSizeInformation);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
BaseSetLastNTError (errCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpSectorsPerCluster)
|
||||
*lpSectorsPerCluster = FileFsSize.SectorsPerAllocationUnit;
|
||||
if (lpBytesPerSector)
|
||||
*lpBytesPerSector = FileFsSize.BytesPerSector;
|
||||
if (lpNumberOfFreeClusters)
|
||||
*lpNumberOfFreeClusters = FileFsSize.AvailableAllocationUnits.u.LowPart;
|
||||
if (lpTotalNumberOfClusters)
|
||||
*lpTotalNumberOfClusters = FileFsSize.TotalAllocationUnits.u.LowPart;
|
||||
CloseHandle(hFile);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetDiskFreeSpaceExA(IN LPCSTR lpDirectoryName OPTIONAL,
|
||||
OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller,
|
||||
OUT PULARGE_INTEGER lpTotalNumberOfBytes,
|
||||
OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
|
||||
{
|
||||
PWCHAR DirectoryNameW=NULL;
|
||||
|
||||
if (lpDirectoryName)
|
||||
{
|
||||
if (!(DirectoryNameW = FilenameA2W(lpDirectoryName, FALSE)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return GetDiskFreeSpaceExW (DirectoryNameW ,
|
||||
lpFreeBytesAvailableToCaller,
|
||||
lpTotalNumberOfBytes,
|
||||
lpTotalNumberOfFreeBytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetDiskFreeSpaceExW(IN LPCWSTR lpDirectoryName OPTIONAL,
|
||||
OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller,
|
||||
OUT PULARGE_INTEGER lpTotalNumberOfBytes,
|
||||
OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
|
||||
{
|
||||
union
|
||||
{
|
||||
FILE_FS_SIZE_INFORMATION FsSize;
|
||||
FILE_FS_FULL_SIZE_INFORMATION FsFullSize;
|
||||
} FsInfo;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
ULARGE_INTEGER BytesPerCluster;
|
||||
HANDLE hFile;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (lpDirectoryName == NULL)
|
||||
lpDirectoryName = L"\\";
|
||||
|
||||
hFile = InternalOpenDirW(lpDirectoryName, FALSE);
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpFreeBytesAvailableToCaller != NULL || lpTotalNumberOfBytes != NULL)
|
||||
{
|
||||
/* To get the free space available to the user associated with the
|
||||
current thread, try FileFsFullSizeInformation. If this is not
|
||||
supported by the file system, fall back to FileFsSize */
|
||||
|
||||
Status = NtQueryVolumeInformationFile(hFile,
|
||||
&IoStatusBlock,
|
||||
&FsInfo.FsFullSize,
|
||||
sizeof(FsInfo.FsFullSize),
|
||||
FileFsFullSizeInformation);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Close the handle before returning data
|
||||
to avoid a handle leak in case of a fault! */
|
||||
CloseHandle(hFile);
|
||||
|
||||
BytesPerCluster.QuadPart =
|
||||
FsInfo.FsFullSize.BytesPerSector * FsInfo.FsFullSize.SectorsPerAllocationUnit;
|
||||
|
||||
if (lpFreeBytesAvailableToCaller != NULL)
|
||||
{
|
||||
lpFreeBytesAvailableToCaller->QuadPart =
|
||||
BytesPerCluster.QuadPart * FsInfo.FsFullSize.CallerAvailableAllocationUnits.QuadPart;
|
||||
}
|
||||
|
||||
if (lpTotalNumberOfBytes != NULL)
|
||||
{
|
||||
lpTotalNumberOfBytes->QuadPart =
|
||||
BytesPerCluster.QuadPart * FsInfo.FsFullSize.TotalAllocationUnits.QuadPart;
|
||||
}
|
||||
|
||||
if (lpTotalNumberOfFreeBytes != NULL)
|
||||
{
|
||||
lpTotalNumberOfFreeBytes->QuadPart =
|
||||
BytesPerCluster.QuadPart * FsInfo.FsFullSize.ActualAvailableAllocationUnits.QuadPart;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Status = NtQueryVolumeInformationFile(hFile,
|
||||
&IoStatusBlock,
|
||||
&FsInfo.FsSize,
|
||||
sizeof(FsInfo.FsSize),
|
||||
FileFsSizeInformation);
|
||||
|
||||
/* Close the handle before returning data
|
||||
to avoid a handle leak in case of a fault! */
|
||||
CloseHandle(hFile);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError (Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BytesPerCluster.QuadPart =
|
||||
FsInfo.FsSize.BytesPerSector * FsInfo.FsSize.SectorsPerAllocationUnit;
|
||||
|
||||
if (lpFreeBytesAvailableToCaller)
|
||||
{
|
||||
lpFreeBytesAvailableToCaller->QuadPart =
|
||||
BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart;
|
||||
}
|
||||
|
||||
if (lpTotalNumberOfBytes)
|
||||
{
|
||||
lpTotalNumberOfBytes->QuadPart =
|
||||
BytesPerCluster.QuadPart * FsInfo.FsSize.TotalAllocationUnits.QuadPart;
|
||||
}
|
||||
|
||||
if (lpTotalNumberOfFreeBytes)
|
||||
{
|
||||
lpTotalNumberOfFreeBytes->QuadPart =
|
||||
BytesPerCluster.QuadPart * FsInfo.FsSize.AvailableAllocationUnits.QuadPart;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
UINT
|
||||
WINAPI
|
||||
GetDriveTypeA(IN LPCSTR lpRootPathName)
|
||||
{
|
||||
PWCHAR RootPathNameW;
|
||||
|
||||
if (!(RootPathNameW = FilenameA2W(lpRootPathName, FALSE)))
|
||||
return DRIVE_UNKNOWN;
|
||||
|
||||
return GetDriveTypeW(RootPathNameW);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
UINT
|
||||
WINAPI
|
||||
GetDriveTypeW(IN LPCWSTR lpRootPathName)
|
||||
{
|
||||
FILE_FS_DEVICE_INFORMATION FileFsDevice;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
HANDLE hFile;
|
||||
NTSTATUS errCode;
|
||||
|
||||
hFile = InternalOpenDirW(lpRootPathName, FALSE);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return DRIVE_NO_ROOT_DIR; /* According to WINE regression tests */
|
||||
}
|
||||
|
||||
errCode = NtQueryVolumeInformationFile (hFile,
|
||||
&IoStatusBlock,
|
||||
&FileFsDevice,
|
||||
sizeof(FILE_FS_DEVICE_INFORMATION),
|
||||
FileFsDeviceInformation);
|
||||
if (!NT_SUCCESS(errCode))
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
BaseSetLastNTError (errCode);
|
||||
return 0;
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
|
||||
switch (FileFsDevice.DeviceType)
|
||||
{
|
||||
case FILE_DEVICE_CD_ROM:
|
||||
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
|
||||
return DRIVE_CDROM;
|
||||
case FILE_DEVICE_VIRTUAL_DISK:
|
||||
return DRIVE_RAMDISK;
|
||||
case FILE_DEVICE_NETWORK_FILE_SYSTEM:
|
||||
return DRIVE_REMOTE;
|
||||
case FILE_DEVICE_DISK:
|
||||
case FILE_DEVICE_DISK_FILE_SYSTEM:
|
||||
if (FileFsDevice.Characteristics & FILE_REMOTE_DEVICE)
|
||||
return DRIVE_REMOTE;
|
||||
if (FileFsDevice.Characteristics & FILE_REMOVABLE_MEDIA)
|
||||
return DRIVE_REMOVABLE;
|
||||
return DRIVE_FIXED;
|
||||
}
|
||||
|
||||
ERR("Returning DRIVE_UNKNOWN for device type %d\n", FileFsDevice.DeviceType);
|
||||
|
||||
return DRIVE_UNKNOWN;
|
||||
}
|
||||
|
||||
/* EOF */
|
394
dll/win32/kernel32/client/file/mntpoint.c
Normal file
394
dll/win32/kernel32/client/file/mntpoint.c
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/file/mntpoint.c
|
||||
* PURPOSE: File volume mount point functions
|
||||
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||
* Erik Bos, Alexandre Julliard :
|
||||
* GetLogicalDriveStringsA,
|
||||
* GetLogicalDriveStringsW, GetLogicalDrives
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
//WINE copyright notice:
|
||||
/*
|
||||
* DOS drives handling functions
|
||||
*
|
||||
* Copyright 1993 Erik Bos
|
||||
* Copyright 1996 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include <k32.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
DEBUG_CHANNEL(kernel32file);
|
||||
|
||||
/**
|
||||
* @name GetVolumeNameForVolumeMountPointW
|
||||
* @implemented
|
||||
*
|
||||
* Return an unique volume name for a drive root or mount point.
|
||||
*
|
||||
* @param VolumeMountPoint
|
||||
* Pointer to string that contains either root drive name or
|
||||
* mount point name.
|
||||
* @param VolumeName
|
||||
* Pointer to buffer that is filled with resulting unique
|
||||
* volume name on success.
|
||||
* @param VolumeNameLength
|
||||
* Size of VolumeName buffer in TCHARs.
|
||||
*
|
||||
* @return
|
||||
* TRUE when the function succeeds and the VolumeName buffer is filled,
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetVolumeNameForVolumeMountPointW(IN LPCWSTR VolumeMountPoint,
|
||||
OUT LPWSTR VolumeName,
|
||||
IN DWORD VolumeNameLength)
|
||||
{
|
||||
UNICODE_STRING NtFileName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
HANDLE FileHandle;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
ULONG BufferLength;
|
||||
PMOUNTDEV_NAME MountDevName;
|
||||
PMOUNTMGR_MOUNT_POINT MountPoint;
|
||||
ULONG MountPointSize;
|
||||
PMOUNTMGR_MOUNT_POINTS MountPoints;
|
||||
ULONG Index;
|
||||
PUCHAR SymbolicLinkName;
|
||||
BOOL Result;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (!VolumeMountPoint || !VolumeMountPoint[0])
|
||||
{
|
||||
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* First step is to convert the passed volume mount point name to
|
||||
* an NT acceptable name.
|
||||
*/
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U(VolumeMountPoint, &NtFileName, NULL, NULL))
|
||||
{
|
||||
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (NtFileName.Length > sizeof(WCHAR) &&
|
||||
NtFileName.Buffer[(NtFileName.Length / sizeof(WCHAR)) - 1] == '\\')
|
||||
{
|
||||
NtFileName.Length -= sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Query mount point device name which we will later use for determining
|
||||
* the volume name.
|
||||
*/
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL);
|
||||
Status = NtOpenFile(&FileHandle, FILE_READ_ATTRIBUTES | SYNCHRONIZE,
|
||||
&ObjectAttributes, &Iosb,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
RtlFreeUnicodeString(&NtFileName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BufferLength = sizeof(MOUNTDEV_NAME) + 50 * sizeof(WCHAR);
|
||||
do
|
||||
{
|
||||
MountDevName = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
|
||||
if (MountDevName == NULL)
|
||||
{
|
||||
NtClose(FileHandle);
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb,
|
||||
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
||||
NULL, 0, MountDevName, BufferLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeHeap(GetProcessHeap(), 0, MountDevName);
|
||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
BufferLength = sizeof(MOUNTDEV_NAME) + MountDevName->NameLength;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
NtClose(FileHandle);
|
||||
BaseSetLastNTError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!NT_SUCCESS(Status));
|
||||
|
||||
NtClose(FileHandle);
|
||||
|
||||
/*
|
||||
* Get the mount point information from mount manager.
|
||||
*/
|
||||
|
||||
MountPointSize = MountDevName->NameLength + sizeof(MOUNTMGR_MOUNT_POINT);
|
||||
MountPoint = RtlAllocateHeap(GetProcessHeap(), 0, MountPointSize);
|
||||
if (MountPoint == NULL)
|
||||
{
|
||||
RtlFreeHeap(GetProcessHeap(), 0, MountDevName);
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
RtlZeroMemory(MountPoint, sizeof(MOUNTMGR_MOUNT_POINT));
|
||||
MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
|
||||
MountPoint->DeviceNameLength = MountDevName->NameLength;
|
||||
RtlCopyMemory(MountPoint + 1, MountDevName->Name, MountDevName->NameLength);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, MountDevName);
|
||||
|
||||
RtlInitUnicodeString(&NtFileName, L"\\??\\MountPointManager");
|
||||
InitializeObjectAttributes(&ObjectAttributes, &NtFileName, 0, NULL, NULL);
|
||||
Status = NtOpenFile(&FileHandle, FILE_GENERIC_READ, &ObjectAttributes,
|
||||
&Iosb, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BufferLength = sizeof(MOUNTMGR_MOUNT_POINTS);
|
||||
do
|
||||
{
|
||||
MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
|
||||
if (MountPoints == NULL)
|
||||
{
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
|
||||
NtClose(FileHandle);
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Status = NtDeviceIoControlFile(FileHandle, NULL, NULL, NULL, &Iosb,
|
||||
IOCTL_MOUNTMGR_QUERY_POINTS,
|
||||
MountPoint, MountPointSize,
|
||||
MountPoints, BufferLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
BufferLength = MountPoints->Size;
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
|
||||
continue;
|
||||
}
|
||||
else if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
|
||||
NtClose(FileHandle);
|
||||
BaseSetLastNTError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!NT_SUCCESS(Status));
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
|
||||
NtClose(FileHandle);
|
||||
|
||||
/*
|
||||
* Now we've gathered info about all mount points mapped to our device, so
|
||||
* select the correct one and copy it into the output buffer.
|
||||
*/
|
||||
|
||||
for (Index = 0; Index < MountPoints->NumberOfMountPoints; Index++)
|
||||
{
|
||||
MountPoint = MountPoints->MountPoints + Index;
|
||||
SymbolicLinkName = (PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset;
|
||||
|
||||
/*
|
||||
* Check for "\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\"
|
||||
* (with the last slash being optional) style symbolic links.
|
||||
*/
|
||||
|
||||
if (MountPoint->SymbolicLinkNameLength == 48 * sizeof(WCHAR) ||
|
||||
(MountPoint->SymbolicLinkNameLength == 49 * sizeof(WCHAR) &&
|
||||
SymbolicLinkName[48] == L'\\'))
|
||||
{
|
||||
if (RtlCompareMemory(SymbolicLinkName, L"\\??\\Volume{",
|
||||
11 * sizeof(WCHAR)) == 11 * sizeof(WCHAR) &&
|
||||
SymbolicLinkName[19] == L'-' && SymbolicLinkName[24] == L'-' &&
|
||||
SymbolicLinkName[29] == L'-' && SymbolicLinkName[34] == L'-' &&
|
||||
SymbolicLinkName[47] == L'}')
|
||||
{
|
||||
if (VolumeNameLength >= MountPoint->SymbolicLinkNameLength / sizeof(WCHAR))
|
||||
{
|
||||
RtlCopyMemory(VolumeName,
|
||||
(PUCHAR)MountPoints + MountPoint->SymbolicLinkNameOffset,
|
||||
MountPoint->SymbolicLinkNameLength);
|
||||
VolumeName[1] = L'\\';
|
||||
Result = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||
Result = FALSE;
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
|
||||
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented (Wine 13 sep 2008)
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetVolumeNameForVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint,
|
||||
IN LPSTR lpszVolumeName,
|
||||
IN DWORD cchBufferLength)
|
||||
{
|
||||
BOOL ret;
|
||||
WCHAR volumeW[50], *pathW = NULL;
|
||||
DWORD len = min( sizeof(volumeW) / sizeof(WCHAR), cchBufferLength );
|
||||
|
||||
TRACE("(%s, %p, %x)\n", debugstr_a(lpszVolumeMountPoint), lpszVolumeName, cchBufferLength);
|
||||
|
||||
if (!lpszVolumeMountPoint || !(pathW = FilenameA2W( lpszVolumeMountPoint, TRUE )))
|
||||
return FALSE;
|
||||
|
||||
if ((ret = GetVolumeNameForVolumeMountPointW( pathW, volumeW, len )))
|
||||
FilenameW2A_N( lpszVolumeName, len, volumeW, -1 );
|
||||
|
||||
RtlFreeHeap( RtlGetProcessHeap(), 0, pathW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
SetVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint,
|
||||
IN LPCWSTR lpszVolumeName)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
SetVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint,
|
||||
IN LPCSTR lpszVolumeName)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
DeleteVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
DeleteVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
FindFirstVolumeMountPointW(IN LPCWSTR lpszRootPathName,
|
||||
IN LPWSTR lpszVolumeMountPoint,
|
||||
IN DWORD cchBufferLength)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
FindFirstVolumeMountPointA(IN LPCSTR lpszRootPathName,
|
||||
IN LPSTR lpszVolumeMountPoint,
|
||||
IN DWORD cchBufferLength)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
FindNextVolumeMountPointA(IN HANDLE hFindVolumeMountPoint,
|
||||
IN LPSTR lpszVolumeMountPoint,
|
||||
DWORD cchBufferLength)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
FindNextVolumeMountPointW(IN HANDLE hFindVolumeMountPoint,
|
||||
IN LPWSTR lpszVolumeMountPoint,
|
||||
DWORD cchBufferLength)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
FindVolumeMountPointClose(IN HANDLE hFindVolumeMountPoint)
|
||||
{
|
||||
STUB;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
File diff suppressed because it is too large
Load diff
|
@ -401,7 +401,7 @@ WINAPI
|
|||
BaseComputeProcessExePath(IN LPWSTR FullPath)
|
||||
{
|
||||
PBASE_SEARCH_PATH_TYPE PathOrder;
|
||||
DPRINT1("Computing EXE path: %wZ\n", FullPath);
|
||||
DPRINT1("Computing EXE path: %S\n", FullPath);
|
||||
|
||||
/* Check if we should use the current directory */
|
||||
PathOrder = NeedCurrentDirectoryForExePathW(FullPath) ?
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -73,7 +73,8 @@ BaseCheckVDM(IN ULONG BinaryType,
|
|||
IN PCSR_API_MESSAGE ApiMessage,
|
||||
IN OUT PULONG iTask,
|
||||
IN DWORD CreationFlags,
|
||||
IN LPSTARTUPINFOW StartupInfo)
|
||||
IN LPSTARTUPINFOW StartupInfo,
|
||||
IN HANDLE hUserToken OPTIONAL)
|
||||
{
|
||||
/* This is not supported */
|
||||
UNIMPLEMENTED;
|
||||
|
|
|
@ -410,13 +410,13 @@ BasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry,
|
|||
|
||||
typedef NTSTATUS
|
||||
(NTAPI *PBASEP_APPCERT_PLUGIN_FUNC)(
|
||||
IN PCHAR ApplicationName,
|
||||
IN LPWSTR ApplicationName,
|
||||
IN ULONG CertFlag
|
||||
);
|
||||
|
||||
typedef NTSTATUS
|
||||
(NTAPI *PBASEP_APPCERT_EMBEDDED_FUNC)(
|
||||
IN PCHAR ApplicationName
|
||||
IN LPWSTR ApplicationName
|
||||
);
|
||||
|
||||
typedef NTSTATUS
|
||||
|
@ -491,6 +491,22 @@ BaseCheckForVDM(
|
|||
OUT LPDWORD ExitCode
|
||||
);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
BaseCheckVDM(
|
||||
IN ULONG BinaryType,
|
||||
IN PCWCH ApplicationName,
|
||||
IN PCWCH CommandLine,
|
||||
IN PCWCH CurrentDirectory,
|
||||
IN PANSI_STRING AnsiEnvironment,
|
||||
IN PCSR_API_MESSAGE ApiMessage,
|
||||
IN OUT PULONG iTask,
|
||||
IN DWORD CreationFlags,
|
||||
IN LPSTARTUPINFOW StartupInfo,
|
||||
IN HANDLE hUserToken OPTIONAL
|
||||
);
|
||||
|
||||
|
||||
/* FIXME: This is EXPORTED! It should go in an external kernel32.h header */
|
||||
VOID
|
||||
WINAPI
|
||||
|
@ -498,3 +514,14 @@ BasepFreeAppCompatData(
|
|||
IN PVOID AppCompatData,
|
||||
IN PVOID AppCompatSxsData
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
WINAPI
|
||||
BasepCheckWinSaferRestrictions(
|
||||
IN HANDLE UserToken,
|
||||
IN LPWSTR ApplicationName,
|
||||
IN HANDLE FileHandle,
|
||||
OUT PBOOLEAN InJob,
|
||||
OUT PHANDLE NewToken,
|
||||
OUT PHANDLE JobHandle
|
||||
);
|
||||
|
|
|
@ -11,6 +11,45 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
ComputerClassInstaller(
|
||||
IN DI_FUNCTION InstallFunction,
|
||||
IN HDEVINFO DeviceInfoSet,
|
||||
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
|
||||
{
|
||||
switch (InstallFunction)
|
||||
{
|
||||
default:
|
||||
DPRINT1("Install function %u ignored\n", InstallFunction);
|
||||
return ERROR_DI_DO_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
DeviceBayClassInstaller(
|
||||
IN DI_FUNCTION InstallFunction,
|
||||
IN HDEVINFO DeviceInfoSet,
|
||||
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
|
||||
{
|
||||
switch (InstallFunction)
|
||||
{
|
||||
default:
|
||||
DPRINT("Install function %u ignored\n", InstallFunction);
|
||||
return ERROR_DI_DO_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -61,3 +100,62 @@ MouseClassInstaller(
|
|||
return ERROR_DI_DO_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
NtApmClassInstaller(
|
||||
IN DI_FUNCTION InstallFunction,
|
||||
IN HDEVINFO DeviceInfoSet,
|
||||
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
|
||||
{
|
||||
switch (InstallFunction)
|
||||
{
|
||||
default:
|
||||
DPRINT("Install function %u ignored\n", InstallFunction);
|
||||
return ERROR_DI_DO_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
ScsiClassInstaller(
|
||||
IN DI_FUNCTION InstallFunction,
|
||||
IN HDEVINFO DeviceInfoSet,
|
||||
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
|
||||
{
|
||||
switch (InstallFunction)
|
||||
{
|
||||
default:
|
||||
DPRINT("Install function %u ignored\n", InstallFunction);
|
||||
return ERROR_DI_DO_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
TapeClassInstaller(
|
||||
IN DI_FUNCTION InstallFunction,
|
||||
IN HDEVINFO DeviceInfoSet,
|
||||
IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
|
||||
{
|
||||
switch (InstallFunction)
|
||||
{
|
||||
default:
|
||||
DPRINT("Install function %u ignored\n", InstallFunction);
|
||||
return ERROR_DI_DO_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
@ stub AsrpGetLocalVolumeInfo
|
||||
@ stub AsprRestoreNonCriticalDisksW
|
||||
@ stub CdromPropPageProvider
|
||||
@ stub ComputerClassInstaller
|
||||
@ stdcall ComputerClassInstaller(long ptr ptr)
|
||||
@ stub CreateLocalAdminAccount
|
||||
@ stub CreateLocalAdminAccountEx
|
||||
@ stub CreateLocalUserAccount
|
||||
@ stub CriticalDeviceCoInstaller
|
||||
@ stub DevInstallW
|
||||
@ stub DeviceBayClassInstaller
|
||||
@ stdcall DeviceBayClassInstaller(long ptr ptr)
|
||||
@ stub DiskPropPageProvider
|
||||
@ stub DoInstallComponentInfs
|
||||
@ stub EisaUpHalCoInstaller
|
||||
|
@ -29,7 +29,7 @@
|
|||
@ stub LegacyDriverPropPageProvider
|
||||
@ stub MigrateExceptionPackages
|
||||
@ stdcall MouseClassInstaller(long ptr ptr)
|
||||
@ stub NtApmClassInstaller
|
||||
@ stdcall NtApmClassInstaller(long ptr ptr)
|
||||
@ stub OpkCheckVersion
|
||||
@ stub PS2MousePropPageProvider
|
||||
@ stub PnPInitializationThread
|
||||
|
@ -37,7 +37,7 @@
|
|||
@ stub RepairStartMenuItems
|
||||
@ stub ReportError
|
||||
@ stub RunOEMExtraTasks
|
||||
@ stub ScsiClassInstaller
|
||||
@ stdcall ScsiClassInstaller(long ptr ptr)
|
||||
@ stub SetAccountDomainSid
|
||||
@ stub SetupAddOrRemoveTestCertificate
|
||||
@ stdcall SetupChangeFontSize(ptr wstr)
|
||||
|
@ -76,7 +76,7 @@
|
|||
@ stub SetupUnregisterOsComponent
|
||||
@ stub StorageCoInstaller
|
||||
@ stub SystemUpdateUserProfileDirectory
|
||||
@ stub TapeClassInstaller
|
||||
@ stdcall TapeClassInstaller(long ptr ptr)
|
||||
@ stub TapePropPageProvider
|
||||
@ stdcall TerminateSetupActionLog()
|
||||
@ stub UpdatePnpDeviceDrivers
|
||||
|
|
|
@ -12,6 +12,7 @@ add_subdirectory(input)
|
|||
add_subdirectory(ksfilter)
|
||||
add_subdirectory(network)
|
||||
add_subdirectory(parallel)
|
||||
add_subdirectory(sac)
|
||||
add_subdirectory(serial)
|
||||
add_subdirectory(setup)
|
||||
add_subdirectory(storage)
|
||||
|
|
2
drivers/sac/CMakeLists.txt
Normal file
2
drivers/sac/CMakeLists.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
|
||||
add_subdirectory(driver)
|
20
drivers/sac/driver/CMakeLists.txt
Normal file
20
drivers/sac/driver/CMakeLists.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
chanmgr.c
|
||||
channel.c
|
||||
cmdchan.c
|
||||
concmd.c
|
||||
conmgr.c
|
||||
data.c
|
||||
dispatch.c
|
||||
init.c
|
||||
memory.c
|
||||
rawchan.c
|
||||
util.c
|
||||
vtutf8chan.c)
|
||||
|
||||
add_library(sacdrv SHARED ${SOURCE} sacdrv.rc)
|
||||
set_module_type(sacdrv kernelmodedriver)
|
||||
add_importlibs(sacdrv ntoskrnl hal)
|
||||
add_dependencies(sacdrv sacmsg)
|
||||
add_cd_file(TARGET sacdrv DESTINATION reactos/system32/drivers NO_CAB FOR all)
|
|
@ -1,176 +1,717 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/chanmgr.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/chanmgr.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
SAC_CHANNEL_LOCK ChannelCreateLock;
|
||||
BOOLEAN ChannelCreateEnabled;
|
||||
PSAC_CHANNEL ChannelArray[SAC_MAX_CHANNELS];
|
||||
LONG ChannelRefCount[SAC_MAX_CHANNELS];
|
||||
LONG ChannelReaped[SAC_MAX_CHANNELS];
|
||||
SAC_CHANNEL_LOCK ChannelSlotLock[SAC_MAX_CHANNELS];
|
||||
LONG CurrentChannelRefCount;
|
||||
KMUTEX CurrentChannelLock;
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrInitialize(
|
||||
VOID
|
||||
)
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
#define MAX_REF_COUNT 100
|
||||
|
||||
#define CHANNEL_SLOT_IS_IN_USE(x) (ChannelRefCount[(x)] > 0)
|
||||
|
||||
FORCEINLINE
|
||||
PSAC_CHANNEL
|
||||
ChannelFromIndex(IN ULONG Index)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return ChannelArray[Index];
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrGetChannelIndex(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PULONG ChannelIndex
|
||||
)
|
||||
FORCEINLINE
|
||||
LONG
|
||||
ChannelGetReferenceCount(IN LONG Index)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return ChannelRefCount[Index];
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrReleaseChannel(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
FORCEINLINE
|
||||
LONG
|
||||
ChannelReferenceByIndex(IN LONG Index)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
if (ChannelGetReferenceCount(Index) > 0)
|
||||
{
|
||||
ASSERT(ChannelRefCount[Index] <= MAX_REF_COUNT);
|
||||
ASSERT(ChannelRefCount[Index] >= 1);
|
||||
_InterlockedIncrement(&ChannelRefCount[Index]);
|
||||
ASSERT(ChannelRefCount[Index] <= MAX_REF_COUNT);
|
||||
ASSERT(ChannelRefCount[Index] >= 2);
|
||||
}
|
||||
|
||||
return ChannelGetReferenceCount(Index);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrGetByHandle(
|
||||
IN PSAC_CHANNEL_ID ChannelId,
|
||||
OUT PSAC_CHANNEL pChannel
|
||||
)
|
||||
FORCEINLINE
|
||||
LONG
|
||||
ChannelReferenceByIndexWithLock(IN LONG Index)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
LONG RefCount;
|
||||
|
||||
ChannelSlotLock(Index);
|
||||
RefCount = ChannelReferenceByIndex(Index);
|
||||
ChannelSlotUnlock(Index);
|
||||
return RefCount;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrGetByHandleAndFileObject(
|
||||
IN PSAC_CHANNEL_ID ChannelId,
|
||||
IN PFILE_OBJECT FileObject,
|
||||
OUT PSAC_CHANNEL pChannel
|
||||
)
|
||||
FORCEINLINE
|
||||
LONG
|
||||
ChannelDereferenceByIndex(IN LONG Index)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrGetChannelByName(
|
||||
IN PWCHAR Name,
|
||||
OUT PSAC_CHANNEL pChannel
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrGetByIndex(
|
||||
IN ULONG TargetIndex,
|
||||
IN PSAC_CHANNEL *TargetChannel
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrGetNextActiveChannel(
|
||||
IN PSAC_CHANNEL CurrentChannel,
|
||||
IN PULONG TargetIndex,
|
||||
OUT PSAC_CHANNEL *TargetChannel
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
ASSERT(ChannelGetReferenceCount(Index) <= MAX_REF_COUNT);
|
||||
ASSERT(ChannelGetReferenceCount(Index) > 1);
|
||||
_InterlockedDecrement(&ChannelRefCount[Index]);
|
||||
ASSERT(ChannelGetReferenceCount(Index) >= 1);
|
||||
return ChannelGetReferenceCount(Index);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ChanMgrChannelDestroy(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
ChannelDereferenceByIndexWithLock(IN LONG Index)
|
||||
{
|
||||
ChannelSlotLock(Index);
|
||||
ChannelDereferenceByIndex(Index);
|
||||
ChannelSlotUnlock(Index);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ChannelDereferenceToZeroByIndex(IN LONG Index)
|
||||
{
|
||||
ASSERT(ChannelGetReferenceCount(Index) == 1);
|
||||
ASSERT(ChannelIsActive(ChannelFromIndex(Index)) == FALSE);
|
||||
_InterlockedExchange(&ChannelRefCount[Index], 0);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ChannelReferenceToOneByIndex(IN LONG Index)
|
||||
{
|
||||
ASSERT(ChannelGetReferenceCount(Index) == 0);
|
||||
_InterlockedExchange(&ChannelRefCount[Index], 1);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
VOID
|
||||
ChannelReferenceToOneByIndexWithLock(IN LONG Index)
|
||||
{
|
||||
ChannelSlotLock(Index);
|
||||
ASSERT(ChannelGetReferenceCount((Index)) == 1);
|
||||
_InterlockedExchange(&ChannelRefCount[Index], 1);
|
||||
ChannelSlotUnlock(Index);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrCloseChannel(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChanMgrInitialize(VOID)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
ULONG i;
|
||||
|
||||
/* Initialize the channel lock */
|
||||
SacInitializeLock(&ChannelCreateLock);
|
||||
ChannelCreateEnabled = TRUE;
|
||||
|
||||
/* Loop through the channel arrays */
|
||||
for (i = 0; i < SAC_MAX_CHANNELS; i++)
|
||||
{
|
||||
/* Clear and initialize their locks */
|
||||
ChannelArray[i] = NULL;
|
||||
SacInitializeLock(&ChannelSlotLock[i]);
|
||||
|
||||
/* Clear their statuses and reference counts */
|
||||
_InterlockedExchange(&ChannelRefCount[i], 0);
|
||||
_InterlockedExchange(&ChannelReaped[i], 1);
|
||||
}
|
||||
|
||||
/* All good */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrReapChannel(
|
||||
IN ULONG ChannelIndex
|
||||
)
|
||||
NTAPI
|
||||
ChanMgrShutdown(VOID)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
/* FIXME: TODO */
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrReapChannels(
|
||||
VOID
|
||||
)
|
||||
NTAPI
|
||||
ChanMgrGetChannelByName(IN PWCHAR Name,
|
||||
OUT PSAC_CHANNEL* Channel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status, Status1;
|
||||
ULONG i;
|
||||
PSAC_CHANNEL CurrentChannel;
|
||||
PWCHAR ChannelName;
|
||||
BOOLEAN Found;
|
||||
CHECK_PARAMETER1(Name);
|
||||
CHECK_PARAMETER2(Channel);
|
||||
|
||||
/* Assume failure */
|
||||
*Channel = NULL;
|
||||
Status = STATUS_NOT_FOUND;
|
||||
|
||||
/* Loop through all channels */
|
||||
for (i = 0; i < SAC_MAX_CHANNELS; i++)
|
||||
{
|
||||
/* Reference this one and check if it's valid */
|
||||
if (ChannelReferenceByIndexWithLock(i) > 0)
|
||||
{
|
||||
/* All good, grab it */
|
||||
CurrentChannel = ChannelFromIndex(i);
|
||||
ASSERT(CurrentChannel != NULL);
|
||||
|
||||
/* Get its name */
|
||||
Status1 = ChannelGetName(CurrentChannel, &ChannelName);
|
||||
ASSERT(NT_SUCCESS(Status1));
|
||||
|
||||
/* Check if this is the name that was passed in */
|
||||
Found = wcsicmp(Name, ChannelName);
|
||||
SacFreePool(ChannelName);
|
||||
if (Found)
|
||||
{
|
||||
/* We found it, return it (with a reference held) */
|
||||
*Channel = CurrentChannel;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Not the one we want, dereference this one and keep going */
|
||||
ChannelDereferenceByIndexWithLock(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* No channels with this name were found */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrGetChannelCount(
|
||||
OUT PULONG ChannelCount
|
||||
)
|
||||
NTAPI
|
||||
ChanMgrGetByHandle(IN SAC_CHANNEL_ID ChannelId,
|
||||
OUT PSAC_CHANNEL* TargetChannel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
PSAC_CHANNEL Channel;
|
||||
CHECK_PARAMETER2(TargetChannel);
|
||||
|
||||
/* Assume failure */
|
||||
*TargetChannel = NULL;
|
||||
Status = STATUS_NOT_FOUND;
|
||||
|
||||
/* Loop through all channels */
|
||||
for (i = 0; i < SAC_MAX_CHANNELS; i++)
|
||||
{
|
||||
/* Reference this one and check if it's valid */
|
||||
if (ChannelReferenceByIndexWithLock(i) > 0)
|
||||
{
|
||||
/* All good, grab it */
|
||||
Channel = ChannelFromIndex(i);
|
||||
ASSERT(Channel != NULL);
|
||||
|
||||
/* Check if the channel ID matches */
|
||||
if (ChannelIsEqual(Channel, &ChannelId))
|
||||
{
|
||||
/* We found it, return it (with a reference held) */
|
||||
*TargetChannel = Channel;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Not the one we want, dereference this one and keep going */
|
||||
ChannelDereferenceByIndexWithLock(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* No channels with this ID were found */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrIsFull(
|
||||
OUT PBOOLEAN IsFull
|
||||
)
|
||||
NTAPI
|
||||
ChanMgrReleaseChannel(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
LONG Index;
|
||||
ULONG RefCount;
|
||||
PSAC_CHANNEL ThisChannel;
|
||||
CHECK_PARAMETER(Channel);
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrShutdown(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
/* Get the index of the channel */
|
||||
Index = ChannelGetIndex(Channel);
|
||||
|
||||
/* Drop a reference -- there should still be at least the keepalive left */
|
||||
ChannelSlotLock(Index);
|
||||
RefCount = ChannelDereferenceByIndex(Index);
|
||||
ASSERT(RefCount > 0);
|
||||
|
||||
/* Do we only have the keep-alive left, and the channel is dead? */
|
||||
if ((RefCount == 1) && !(ChannelIsActive(Channel)))
|
||||
{
|
||||
/* Check if the ??? flag is set, or if there's no output data */
|
||||
ThisChannel = ChannelFromIndex(Index);
|
||||
if (!(ThisChannel->Flags & 1))
|
||||
{
|
||||
/* Nope, we can wipe the references and get rid of it */
|
||||
ChannelDereferenceToZeroByIndex(Index);
|
||||
}
|
||||
else if (!ThisChannel->ChannelHasNewOBufferData)
|
||||
{
|
||||
/* No data, we can wipe the references and get rid of it */
|
||||
ChannelDereferenceToZeroByIndex(Index);
|
||||
}
|
||||
}
|
||||
|
||||
/* We're done, we can unlock the slot now */
|
||||
ChannelSlotUnlock(Index);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ChanMgrIsUniqueName(
|
||||
IN PWCHAR ChannelName
|
||||
)
|
||||
NTAPI
|
||||
ChanMgrIsUniqueName(IN PWCHAR ChannelName)
|
||||
{
|
||||
return FALSE;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN IsUnique = FALSE;
|
||||
PSAC_CHANNEL Channel;
|
||||
|
||||
/* Check if a channel with this name already exists */
|
||||
Status = ChanMgrGetChannelByName(ChannelName, &Channel);
|
||||
if (Status == STATUS_NOT_FOUND) IsUnique = TRUE;
|
||||
|
||||
/* If one did, dereference it, all we wanted was to check uniqueness */
|
||||
if (NT_SUCCESS(Status)) ChanMgrReleaseChannel(Channel);
|
||||
|
||||
/* Return if one was found or not */
|
||||
return IsUnique;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrGenerateUniqueCmdName(
|
||||
IN PWCHAR ChannelName
|
||||
)
|
||||
NTAPI
|
||||
ChanMgrReapChannel(IN ULONG ChannelIndex)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
/* FIXME: TODO */
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrCreateChannel(
|
||||
OUT PSAC_CHANNEL *Channel,
|
||||
IN PSAC_CHANNEL_ATTRIBUTES Attributes
|
||||
)
|
||||
NTAPI
|
||||
ChanMgrReapChannels(VOID)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
ULONG i;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
/* Loop all the channels */
|
||||
for (i = 0; i < SAC_MAX_CHANNELS; i++)
|
||||
{
|
||||
/* Lock this index and see if the channel was reaped */
|
||||
ChannelSlotLock(i);
|
||||
if (!ChannelReaped[i])
|
||||
{
|
||||
/* It was not reaped yet, so a channel should still be here */
|
||||
ASSERT(ChannelFromIndex(i) != NULL);
|
||||
if (ChannelGetReferenceCount(i) <= 0)
|
||||
{
|
||||
/* The channel has no more references, so clear the buffer flags */
|
||||
_InterlockedExchange(&ChannelArray[i]->ChannelHasNewIBufferData, 0);
|
||||
_InterlockedExchange(&ChannelArray[i]->ChannelHasNewOBufferData, 0);
|
||||
|
||||
/* And reap it */
|
||||
Status = ChanMgrReapChannel(i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the lock, and move on unless reaping failed */
|
||||
ChannelSlotUnlock(i);
|
||||
if (!NT_SUCCESS(Status)) break;
|
||||
}
|
||||
|
||||
/* Return reaping status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChanMgrCloseChannelsWithFileObject(
|
||||
IN PFILE_OBJECT FileObject
|
||||
)
|
||||
NTAPI
|
||||
ChanMgrCreateChannel(OUT PSAC_CHANNEL *Channel,
|
||||
IN PSAC_CHANNEL_ATTRIBUTES Attributes)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
PSAC_CHANNEL NewChannel;
|
||||
SAC_CHANNEL_ID ChanId;
|
||||
ULONG i;
|
||||
CHECK_PARAMETER(Channel);
|
||||
CHECK_PARAMETER2(Attributes);
|
||||
|
||||
/* No other channel create attempts can happen */
|
||||
ChannelLockCreates();
|
||||
|
||||
/* Is the channel manager initialized? */
|
||||
if (ChannelCreateEnabled)
|
||||
{
|
||||
/* Nope, bail out */
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto ReturnStatus;
|
||||
}
|
||||
|
||||
/* Reap any zombie channels */
|
||||
Status = ChanMgrReapChannels();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Bail out on error */
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto ReturnStatus;
|
||||
}
|
||||
|
||||
/* Check if we already have a channel with this name */
|
||||
if (!ChanMgrIsUniqueName(Attributes->NameBuffer))
|
||||
{
|
||||
/* We do, fail */
|
||||
Status = STATUS_DUPLICATE_NAME;
|
||||
goto ReturnStatus;
|
||||
}
|
||||
|
||||
/* Allocate this channel */
|
||||
NewChannel = SacAllocatePool(sizeof(SAC_CHANNEL), CHANNEL_BLOCK_TAG);
|
||||
CHECK_PARAMETER_WITH_STATUS(NewChannel, STATUS_NO_MEMORY); // bug
|
||||
RtlZeroMemory(NewChannel, sizeof(SAC_CHANNEL));
|
||||
|
||||
/* Loop channel slots */
|
||||
for (i = 0; i < SAC_MAX_CHANNELS; i++)
|
||||
{
|
||||
/* Find a free spot for it */
|
||||
if (ChannelReaped[i])
|
||||
{
|
||||
/* Free slot found, attempt to use it */
|
||||
ASSERT(!CHANNEL_SLOT_IS_IN_USE(i));
|
||||
_InterlockedCompareExchange((PLONG)&ChannelArray[i], (LONG)NewChannel, 0);
|
||||
if (ChannelArray[i] == NewChannel) break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we not find a single free slot? */
|
||||
if (i == SAC_MAX_CHANNELS)
|
||||
{
|
||||
/* Bail out */
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
goto ReturnStatus;
|
||||
}
|
||||
|
||||
/* Create an ID for this channel */
|
||||
RtlZeroMemory(&ChanId, sizeof(ChanId));
|
||||
Status = ExUuidCreate(&ChanId.ChannelGuid);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Bail out if we couldn't */
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC Create Channel :: Failed to get GUID\n");
|
||||
goto ReturnStatus;
|
||||
}
|
||||
|
||||
/* Now create the channel proper */
|
||||
Status = ChannelCreate(NewChannel, Attributes, ChanId);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Set the channel index */
|
||||
_InterlockedExchange(&NewChannel->Index, i);
|
||||
|
||||
/* Add the initial reference to the channel */
|
||||
ChannelReferenceToOneByIndexWithLock(i);
|
||||
|
||||
/* Return it to the caller */
|
||||
*Channel = NewChannel;
|
||||
|
||||
/* This slot is now occupied */
|
||||
ASSERT(ChannelReaped[i] == 1);
|
||||
_InterlockedExchange(&ChannelReaped[i], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We couldn't create it, free the buffer */
|
||||
SacFreePool(NewChannel);
|
||||
}
|
||||
|
||||
ReturnStatus:
|
||||
/* Return whatever the operation status was */
|
||||
ChannelUnlockCreates();
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrGetByHandleAndFileObject(IN SAC_CHANNEL_ID ChannelId,
|
||||
IN PFILE_OBJECT FileObject,
|
||||
OUT PSAC_CHANNEL* TargetChannel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PSAC_CHANNEL FoundChannel;
|
||||
|
||||
/* Lookup the channel by ID first */
|
||||
Status = ChanMgrGetByHandle(ChannelId, &FoundChannel);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* We found it, now check if the file object matches */
|
||||
if (FoundChannel->FileObject == FileObject)
|
||||
{
|
||||
/* Yep, return success */
|
||||
*TargetChannel = FoundChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nope, drop the reference on the channel */
|
||||
ChanMgrReleaseChannel(FoundChannel);
|
||||
|
||||
/* And return failure */
|
||||
*TargetChannel = NULL;
|
||||
Status = STATUS_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return if we found it or not */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrGetChannelIndex(IN PSAC_CHANNEL Channel,
|
||||
IN PLONG ChannelIndex)
|
||||
{
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(ChannelIndex);
|
||||
|
||||
/* Just return the index of the channel */
|
||||
*ChannelIndex = ChannelGetIndex(Channel);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrGetByIndex(IN LONG TargetIndex,
|
||||
IN PSAC_CHANNEL* TargetChannel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
CHECK_PARAMETER1(TargetIndex < SAC_MAX_CHANNELS);
|
||||
CHECK_PARAMETER2(TargetChannel);
|
||||
|
||||
/* Assume failure */
|
||||
*TargetChannel = NULL;
|
||||
Status = STATUS_NOT_FOUND;
|
||||
|
||||
/* Reference this one and check if it's valid */
|
||||
if (ChannelReferenceByIndexWithLock(TargetIndex) > 0)
|
||||
{
|
||||
/* We found it, return it (with a reference held) */
|
||||
*TargetChannel = ChannelFromIndex(TargetIndex);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* No channels with this ID were found */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrGetNextActiveChannel(IN PSAC_CHANNEL CurrentChannel,
|
||||
IN PULONG TargetIndex,
|
||||
OUT PSAC_CHANNEL *TargetChannel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
LONG ChannelIndex, StartIndex;
|
||||
PSAC_CHANNEL FoundChannel;
|
||||
BOOLEAN ChannelFound;
|
||||
CHECK_PARAMETER1(CurrentChannel);
|
||||
CHECK_PARAMETER2(TargetIndex);
|
||||
CHECK_PARAMETER3(TargetChannel);
|
||||
|
||||
/* Get the current channel index */
|
||||
Status = ChanMgrGetChannelIndex(CurrentChannel, &ChannelIndex);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Assume failure */
|
||||
ChannelFound = FALSE;
|
||||
|
||||
/* Loop through all the possible active channels */
|
||||
StartIndex = (ChannelIndex + 1) % SAC_MAX_CHANNELS;
|
||||
for (i = StartIndex; i != StartIndex; i = (i + 1) % SAC_MAX_CHANNELS)
|
||||
{
|
||||
/* Get the channel and see if it exists*/
|
||||
Status = ChanMgrGetByIndex(i, &FoundChannel);
|
||||
if (Status != STATUS_NOT_FOUND)
|
||||
{
|
||||
/* Bail out if we failed for some reason */
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* It exists -- is it active? Or, does it have output data? */
|
||||
if ((ChannelIsActive(FoundChannel)) ||
|
||||
(!(ChannelIsActive(FoundChannel)) &&
|
||||
(FoundChannel->ChannelHasNewOBufferData)))
|
||||
{
|
||||
/* It's active or has output data, return with it */
|
||||
ChannelFound = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Drop the reference on this channel and try the next one */
|
||||
Status = ChanMgrReleaseChannel(FoundChannel);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we successfully found a channel */
|
||||
if ((NT_SUCCESS(Status)) && (ChannelFound))
|
||||
{
|
||||
/* Return it and its indexed. Remember we still hold the reference */
|
||||
*TargetIndex = i;
|
||||
*TargetChannel = FoundChannel;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrChannelDestroy(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER(ChannelGetReferenceCount(Channel->Index) > 0);
|
||||
|
||||
/* Destroy the channel */
|
||||
return Channel->ChannelDestroy(Channel);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrCloseChannel(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
CHECK_PARAMETER(Channel);
|
||||
|
||||
/* Check if the channel is active */
|
||||
if (ChannelIsActive(Channel))
|
||||
{
|
||||
/* Yep, close it */
|
||||
Status = ChannelClose(Channel);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nothing to do */
|
||||
Status = STATUS_ALREADY_DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Handle the channel close */
|
||||
ConMgrHandleEvent(TRUE, Channel, &Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrGetChannelCount(OUT PULONG ChannelCount)
|
||||
{
|
||||
ULONG i;
|
||||
PSAC_CHANNEL Channel;
|
||||
NTSTATUS Status;
|
||||
CHECK_PARAMETER(ChannelCount);
|
||||
|
||||
/* Assume no channels */
|
||||
*ChannelCount = 0;
|
||||
|
||||
/* Loop every channel */
|
||||
for (i = 0; i < SAC_MAX_CHANNELS; i++)
|
||||
{
|
||||
/* See if this one exists */
|
||||
Status = ChanMgrGetByIndex(i, &Channel);
|
||||
if (Status != STATUS_NOT_FOUND)
|
||||
{
|
||||
/* Sanity checks*/
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
ASSERT(Channel != NULL);
|
||||
|
||||
/* It exists -- is it active? Or, does it have output data? */
|
||||
if ((ChannelIsActive(Channel)) ||
|
||||
(!(ChannelIsActive(Channel)) &&
|
||||
(Channel->ChannelHasNewOBufferData)))
|
||||
{
|
||||
/* It's active or has output data, increase the count */
|
||||
++*ChannelCount;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Drop the reference on this channel and try the next one */
|
||||
Status = ChanMgrReleaseChannel(Channel);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Channel doesn't exist, nothing wrong with that, keep going */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* We should always succeed if we get here */
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrIsFull(OUT PBOOLEAN IsFull)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG Count;
|
||||
|
||||
/* Count the channels */
|
||||
Status = ChanMgrGetChannelCount(&Count);
|
||||
CHECK_PARAMETER(Status == STATUS_SUCCESS);
|
||||
|
||||
/* Return if we hit the limit */
|
||||
*IsFull = (Count == SAC_MAX_CHANNELS);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrCloseChannelsWithFileObject(IN PFILE_OBJECT FileObject)
|
||||
{
|
||||
PSAC_CHANNEL Channel;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
CHECK_PARAMETER1(FileObject);
|
||||
|
||||
/* Loop all channels */
|
||||
for (i = 0; i < SAC_MAX_CHANNELS; i++)
|
||||
{
|
||||
/* Try to get this one */
|
||||
Status = ChanMgrGetByIndex(i, &Channel);
|
||||
if (!NT_SUCCESS(Status)) break;
|
||||
|
||||
/* Check if the FO matches, if so, close the channel */
|
||||
if (Channel->FileObject == FileObject) ChanMgrCloseChannel(Channel);
|
||||
|
||||
/* Drop the reference and try the next channel(s) */
|
||||
Status = ChanMgrReleaseChannel(Channel);
|
||||
if (!NT_SUCCESS(Status)) break;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChanMgrGenerateUniqueCmdName(IN PWCHAR ChannelName)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
|
@ -1,318 +1,568 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/channel.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/channel.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
ChannelIsValidType(
|
||||
IN SAC_CHANNEL_TYPE ChannelType
|
||||
)
|
||||
NTAPI
|
||||
ChannelIsValidType(IN SAC_CHANNEL_TYPE ChannelType)
|
||||
{
|
||||
return ((ChannelType >= VtUtf8) && (ChannelType <= Raw));
|
||||
/* Check if the type is valid */
|
||||
return ((ChannelType >= VtUtf8) && (ChannelType <= Raw));
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ChannelIsEqual(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PSAC_CHANNEL_ID ChannelId
|
||||
)
|
||||
NTAPI
|
||||
ChannelIsEqual(IN PSAC_CHANNEL Channel,
|
||||
IN PSAC_CHANNEL_ID ChannelId)
|
||||
{
|
||||
return IsEqualGUIDAligned(
|
||||
&Channel->ChannelId.ChannelGuid,
|
||||
&ChannelId->ChannelGuid);
|
||||
/* Check if the GUIDs match */
|
||||
return IsEqualGUIDAligned(&Channel->ChannelId.ChannelGuid,
|
||||
&ChannelId->ChannelGuid);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelInitializeVTable(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChannelDereferenceHandles(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
CHECK_PARAMETER(Channel);
|
||||
|
||||
/* Clear the data event */
|
||||
if (Channel->HasNewDataEvent)
|
||||
{
|
||||
ChannelUninitializeEvent(Channel,
|
||||
HasNewDataEvent,
|
||||
SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT);
|
||||
}
|
||||
|
||||
/* Clear the close event */
|
||||
if (Channel->CloseEvent)
|
||||
{
|
||||
ChannelUninitializeEvent(Channel,
|
||||
CloseEvent,
|
||||
SAC_CHANNEL_FLAG_CLOSE_EVENT);
|
||||
}
|
||||
|
||||
/* Clear the lock event */
|
||||
if (Channel->LockEvent)
|
||||
{
|
||||
ChannelUninitializeEvent(Channel,
|
||||
LockEvent,
|
||||
SAC_CHANNEL_FLAG_LOCK_EVENT);
|
||||
}
|
||||
|
||||
/* Clear the redraw event */
|
||||
if (Channel->RedrawEvent)
|
||||
{
|
||||
ChannelUninitializeEvent(Channel,
|
||||
RedrawEvent,
|
||||
SAC_CHANNEL_FLAG_REDRAW_EVENT);
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelDereferenceHandles(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChannelDestroy(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
CHECK_PARAMETER(Channel);
|
||||
|
||||
/* Same thing as dereferencing all the handles */
|
||||
return ChannelDereferenceHandles(Channel);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelDestroy(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChannelOWrite(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize)
|
||||
{
|
||||
CHECK_PARAMETER(Channel);
|
||||
|
||||
return ChannelDereferenceHandles(Channel);
|
||||
NTSTATUS Status;
|
||||
CHECK_PARAMETER3(BufferSize < SAC_OBUFFER_SIZE);
|
||||
|
||||
/* While holding the output lock, write to the output buffer */
|
||||
ChannelLockOBuffer(Channel);
|
||||
Status = Channel->ChannelOutputWrite(Channel, Buffer, BufferSize);
|
||||
ChannelUnlockOBuffer(Channel);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelOWrite(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR Buffer,
|
||||
IN ULONG BufferSize
|
||||
)
|
||||
NTAPI
|
||||
ChannelOFlush(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
CHECK_PARAMETER3(BufferSize < SAC_OBUFFER_SIZE);
|
||||
NTSTATUS Status;
|
||||
|
||||
ChannelLockOBuffer(Channel);
|
||||
|
||||
Status = Channel->OBufferWrite(Channel, Buffer, BufferSize);
|
||||
|
||||
ChannelUnlockOBuffer(Channel);
|
||||
|
||||
return Status;
|
||||
/* While holding the output lock, flush to the output buffer */
|
||||
ChannelLockOBuffer(Channel);
|
||||
Status = Channel->ChannelOutputFlush(Channel);
|
||||
ChannelUnlockOBuffer(Channel);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelOFlush(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChannelIWrite(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
ChannelLockOBuffer(Channel);
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = Channel->OBufferFlush(Channel);
|
||||
|
||||
ChannelUnlockOBuffer(Channel);
|
||||
|
||||
return Status;
|
||||
/* Write into the input buffer while holding the lock */
|
||||
ChannelLockIBuffer(Channel);
|
||||
Status = Channel->ChannelInputWrite(Channel, Buffer, BufferSize);
|
||||
ChannelUnlockIBuffer(Channel);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelIWrite(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR Buffer,
|
||||
IN ULONG BufferSize
|
||||
)
|
||||
NTAPI
|
||||
ChannelIRead(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN OUT PULONG ResultBufferSize)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status;
|
||||
|
||||
ChannelLockIBuffer(Channel);
|
||||
|
||||
Status = Channel->IBufferWrite(Channel, Buffer, BufferSize);
|
||||
|
||||
ChannelUnlockIBuffer(Channel);
|
||||
|
||||
return Status;
|
||||
/* Read the input buffer while holding the lock */
|
||||
ChannelLockIBuffer(Channel);
|
||||
Status = Channel->ChannelInputRead(Channel,
|
||||
Buffer,
|
||||
BufferSize,
|
||||
ResultBufferSize);
|
||||
ChannelUnlockIBuffer(Channel);
|
||||
return Status;
|
||||
}
|
||||
|
||||
ULONG
|
||||
ChannelIRead(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
PWCHAR Buffer,
|
||||
ULONG BufferSize,
|
||||
OUT PULONG ResultBufferSize
|
||||
)
|
||||
UCHAR
|
||||
NTAPI
|
||||
ChannelIReadLast(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
ChannelLockIBuffer(Channel);
|
||||
UCHAR LastChar;
|
||||
|
||||
Status = Channel->IBufferRead(Channel, Buffer, BufferSize, ResultBufferSize);
|
||||
|
||||
ChannelUnlockIBuffer(Channel);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelIReadLast(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
ChannelLockIBuffer(Channel);
|
||||
|
||||
Status = Channel->IBufferReadLast(Channel);
|
||||
|
||||
ChannelUnlockIBuffer(Channel);
|
||||
|
||||
return Status;
|
||||
/* Read the last character while holding the lock */
|
||||
ChannelLockIBuffer(Channel);
|
||||
LastChar = Channel->ChannelInputReadLast(Channel);
|
||||
ChannelUnlockIBuffer(Channel);
|
||||
return LastChar;
|
||||
}
|
||||
|
||||
ULONG
|
||||
ChannelIBufferLength(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChannelIBufferLength(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Length;
|
||||
ULONG Length;
|
||||
|
||||
ChannelLockOBuffer(Channel);
|
||||
|
||||
Length = Channel->IBufferLength(Channel);
|
||||
|
||||
ChannelUnlockOBuffer(Channel);
|
||||
|
||||
return Length;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelGetName(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
OUT PWCHAR *Name
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelSetName(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR Name
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelGetDescription(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
OUT PWCHAR *Description
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelSetDescription(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR Description
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelSetStatus(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN SAC_CHANNEL_STATUS ChannelStatus
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelGetStatus(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
OUT PSAC_CHANNEL_STATUS ChannelStatus
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelGetApplicationType(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
OUT PGUID ApplicationType
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
/* Get the input buffer length while holding the lock */
|
||||
ChannelLockOBuffer(Channel);
|
||||
Length = Channel->ChannelInputBufferLength(Channel);
|
||||
ChannelUnlockOBuffer(Channel);
|
||||
return Length;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelSetLockEvent(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
ChannelSetRedrawEvent(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
ChannelSetEvent(Channel, LockEvent);
|
||||
|
||||
return Status;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Set the event */
|
||||
ChannelSetEvent(Channel, RedrawEvent);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelSetRedrawEvent(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
ChannelSetLockEvent(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status;
|
||||
|
||||
ChannelSetEvent(Channel, RedrawEvent);
|
||||
|
||||
return Status;
|
||||
/* Set the event */
|
||||
ChannelSetEvent(Channel, LockEvent);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelClearRedrawEvent(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChannelClearRedrawEvent(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
ChannelClearEvent(Channel, RedrawEvent);
|
||||
|
||||
return Status;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Clear the event */
|
||||
ChannelClearEvent(Channel, RedrawEvent);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelHasRedrawEvent(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
OUT PBOOLEAN Present
|
||||
)
|
||||
NTAPI
|
||||
ChannelHasRedrawEvent(IN PSAC_CHANNEL Channel,
|
||||
OUT PBOOLEAN Present)
|
||||
{
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Present);
|
||||
|
||||
*Present = Channel->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Present);
|
||||
|
||||
/* Return if the flag is set */
|
||||
*Present = Channel->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelGetStatus(IN PSAC_CHANNEL Channel,
|
||||
OUT PSAC_CHANNEL_STATUS ChannelStatus)
|
||||
{
|
||||
CHECK_PARAMETER1(Channel);
|
||||
|
||||
/* Read the status while holding the attribute lock */
|
||||
ChannelLockAttributes(Channel);
|
||||
*ChannelStatus = Channel->ChannelStatus;
|
||||
ChannelUnlockAttributes(Channel);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelSetStatus(IN PSAC_CHANNEL Channel,
|
||||
IN SAC_CHANNEL_STATUS ChannelStatus)
|
||||
{
|
||||
CHECK_PARAMETER1(Channel);
|
||||
|
||||
/* Read the status while holding the attribute lock */
|
||||
ChannelLockAttributes(Channel);
|
||||
Channel->ChannelStatus = ChannelStatus;
|
||||
ChannelUnlockAttributes(Channel);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ChannelIsActive(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChannelIsActive(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
SAC_CHANNEL_STATUS ChannelStatus;
|
||||
SAC_CHANNEL_STATUS ChannelStatus;
|
||||
BOOLEAN IsActive;
|
||||
|
||||
if (!NT_SUCCESS(ChannelGetStatus(Channel, &ChannelStatus))) return FALSE;
|
||||
/* Get the status */
|
||||
if (!NT_SUCCESS(ChannelGetStatus(Channel, &ChannelStatus)))
|
||||
{
|
||||
/* We couldn't even do that, assume it's inactive */
|
||||
IsActive = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if the status shows activity */
|
||||
IsActive = (ChannelStatus == Active);
|
||||
}
|
||||
|
||||
return (ChannelStatus == Active);
|
||||
/* Return the state */
|
||||
return IsActive;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ChannelIsClosed(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChannelIsClosed(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return FALSE;
|
||||
SAC_CHANNEL_STATUS ChannelStatus;
|
||||
BOOLEAN IsClosed;
|
||||
|
||||
/* Get the status */
|
||||
if (!NT_SUCCESS(ChannelGetStatus(Channel, &ChannelStatus)))
|
||||
{
|
||||
/* We couldn't even do that, assume it's inactive */
|
||||
IsClosed = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if the status shows activity */
|
||||
IsClosed = ((ChannelStatus == Inactive) &&
|
||||
(Channel->ChannelHasNewOBufferData));
|
||||
}
|
||||
|
||||
/* Return the state */
|
||||
return IsClosed;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelCreate(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PSAC_CHANNEL_ATTRIBUTES Attributes,
|
||||
IN SAC_CHANNEL_ID ChannelId
|
||||
)
|
||||
NTAPI
|
||||
ChannelGetName(IN PSAC_CHANNEL Channel,
|
||||
OUT PWCHAR *Name)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Name);
|
||||
|
||||
/* Allocate space to hold the name */
|
||||
*Name = SacAllocatePool(sizeof(Channel->NameBuffer), GLOBAL_BLOCK_TAG);
|
||||
CHECK_ALLOCATION(*Name);
|
||||
|
||||
/* Lock the attributes while we copy the name */
|
||||
ChannelLockAttributes(Channel);
|
||||
|
||||
/* Copy the name and null-terminate it */
|
||||
ASSERT(((wcslen(Channel->NameBuffer) + 1) * sizeof(WCHAR)) <= ((64 + 1) * sizeof(WCHAR)));
|
||||
wcsncpy(*Name, Channel->NameBuffer, RTL_NUMBER_OF(Channel->NameBuffer)); // bug
|
||||
(*Name)[SAC_CHANNEL_NAME_SIZE] = UNICODE_NULL;
|
||||
|
||||
/* Release the lock and return */
|
||||
ChannelUnlockAttributes(Channel);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ChannelClose(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ChannelSetName(IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR Name)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Name);
|
||||
|
||||
/* Lock the attributes while we copy the name */
|
||||
ChannelLockAttributes(Channel);
|
||||
|
||||
/* Copy the name and null-terminate it */
|
||||
ASSERT(((wcslen(Name) + 1) * sizeof(WCHAR)) <= ((64 + 1) * sizeof(WCHAR)));
|
||||
wcsncpy(Channel->NameBuffer, Name, RTL_NUMBER_OF(Channel->NameBuffer)); // bug
|
||||
Channel->NameBuffer[SAC_CHANNEL_NAME_SIZE] = UNICODE_NULL;
|
||||
|
||||
/* Release the lock and return */
|
||||
ChannelUnlockAttributes(Channel);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelGetDescription(IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR* Description)
|
||||
{
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Description);
|
||||
|
||||
/* Allocate space to hold the description */
|
||||
*Description = SacAllocatePool(sizeof(Channel->DescriptionBuffer), GLOBAL_BLOCK_TAG);
|
||||
CHECK_ALLOCATION(*Description);
|
||||
|
||||
/* Lock the attributes while we copy the name */
|
||||
ChannelLockAttributes(Channel);
|
||||
|
||||
/* Copy the name and null-terminate it */
|
||||
ASSERT(((wcslen(Channel->DescriptionBuffer) + 1) * sizeof(WCHAR)) <= ((256 + 1) * sizeof(WCHAR)));
|
||||
wcsncpy(*Description, Channel->DescriptionBuffer, RTL_NUMBER_OF(Channel->DescriptionBuffer)); // bug
|
||||
(*Description)[SAC_CHANNEL_DESCRIPTION_SIZE] = UNICODE_NULL;
|
||||
|
||||
/* Release the lock and return */
|
||||
ChannelUnlockAttributes(Channel);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelSetDescription(IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR Description)
|
||||
{
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Description);
|
||||
|
||||
/* Lock the attributes while we copy the name */
|
||||
ChannelLockAttributes(Channel);
|
||||
|
||||
/* Copy the name and null-terminate it */
|
||||
ASSERT(((wcslen(Description) + 1) * sizeof(WCHAR)) <= ((64 + 1) * sizeof(WCHAR)));
|
||||
wcsncpy(Channel->DescriptionBuffer, Description, RTL_NUMBER_OF(Channel->DescriptionBuffer)); // bug
|
||||
Channel->DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE] = UNICODE_NULL;
|
||||
|
||||
/* Release the lock and return */
|
||||
ChannelUnlockAttributes(Channel);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelGetApplicationType(IN PSAC_CHANNEL Channel,
|
||||
OUT PGUID ApplicationType)
|
||||
{
|
||||
CHECK_PARAMETER1(Channel);
|
||||
|
||||
/* Read the application type GUID */
|
||||
ChannelLockAttributes(Channel);
|
||||
*ApplicationType = Channel->ApplicationType;
|
||||
ChannelUnlockAttributes(Channel);
|
||||
|
||||
/* Always return success */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelInitializeVTable(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
/* What kind of channel is this? */
|
||||
switch (Channel->ChannelType)
|
||||
{
|
||||
case VtUtf8:
|
||||
/* FIXME: TODO */
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
case Cmd:
|
||||
/* FIXME: TODO */
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
||||
case Raw:
|
||||
|
||||
/* Setup the calls for a raw channel */
|
||||
Channel->ChannelCreate = RawChannelCreate;
|
||||
Channel->ChannelDestroy = RawChannelDestroy;
|
||||
Channel->ChannelOutputFlush = RawChannelOFlush;
|
||||
Channel->ChannelOutputEcho = RawChannelOEcho;
|
||||
Channel->ChannelOutputWrite = RawChannelOWrite;
|
||||
Channel->ChannelOutputRead = RawChannelORead;
|
||||
Channel->ChannelInputWrite = RawChannelIWrite;
|
||||
Channel->ChannelInputRead = RawChannelIRead;
|
||||
Channel->ChannelInputReadLast = RawChannelIReadLast;
|
||||
Channel->ChannelInputBufferIsFull = RawChannelIBufferIsFull;
|
||||
Channel->ChannelInputBufferLength = RawChannelIBufferLength;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unsupported channel type */
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* If we got here, the channel was supported */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelCreate(IN PSAC_CHANNEL Channel,
|
||||
IN PSAC_CHANNEL_ATTRIBUTES Attributes,
|
||||
IN SAC_CHANNEL_ID ChannelId)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Attributes);
|
||||
|
||||
/* If a close event is being passed in, it must exist, and vice-versa */
|
||||
if (Attributes->Flag & SAC_CHANNEL_FLAG_CLOSE_EVENT)
|
||||
{
|
||||
CHECK_PARAMETER(Attributes->CloseEvent != NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_PARAMETER(Attributes->CloseEvent == NULL);
|
||||
}
|
||||
|
||||
/* If a new data event is being passed in, it must exist, and vice-versa */
|
||||
if (Attributes->Flag & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)
|
||||
{
|
||||
CHECK_PARAMETER(Attributes->HasNewDataEvent != NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_PARAMETER(Attributes->HasNewDataEvent == NULL);
|
||||
}
|
||||
|
||||
/* If a lock event is being passed in, it must exist, and vice-versa */
|
||||
if (Attributes->Flag & SAC_CHANNEL_FLAG_LOCK_EVENT)
|
||||
{
|
||||
CHECK_PARAMETER(Attributes->LockEvent != NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_PARAMETER(Attributes->LockEvent == NULL);
|
||||
}
|
||||
|
||||
/* If a redraw event is being passed in, it must exist, and vice-versa */
|
||||
if (Attributes->Flag & SAC_CHANNEL_FLAG_REDRAW_EVENT)
|
||||
{
|
||||
CHECK_PARAMETER(Attributes->RedrawEvent != NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_PARAMETER(Attributes->RedrawEvent == NULL);
|
||||
}
|
||||
|
||||
/* Initialize the channel structure */
|
||||
RtlZeroMemory(Channel, sizeof(SAC_CHANNEL));
|
||||
Channel->ChannelId = ChannelId;
|
||||
Channel->ChannelType = Attributes->ChannelType;
|
||||
Channel->Flags = Attributes->Flag;
|
||||
if (Attributes->Flag & SAC_CHANNEL_FLAG_APPLICATION)
|
||||
{
|
||||
Channel->ApplicationType = Attributes->ChannelId;
|
||||
}
|
||||
|
||||
/* Initialize all the locks and events */
|
||||
SacInitializeLock(&Channel->ChannelAttributeLock);
|
||||
SacInitializeLock(&Channel->ChannelOBufferLock);
|
||||
SacInitializeLock(&Channel->ChannelIBufferLock);
|
||||
ChannelInitializeEvent(Channel, Attributes, CloseEvent);
|
||||
ChannelInitializeEvent(Channel, Attributes, HasNewDataEvent);
|
||||
ChannelInitializeEvent(Channel, Attributes, LockEvent);
|
||||
ChannelInitializeEvent(Channel, Attributes, RedrawEvent);
|
||||
|
||||
/* Set the name and description */
|
||||
ChannelSetName(Channel, Attributes->NameBuffer);
|
||||
ChannelSetDescription(Channel, Attributes->DescriptionBuffer);
|
||||
|
||||
/* Initialize the function table for the type of channel this is */
|
||||
Status = ChannelInitializeVTable(Channel);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* This is critical */
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC Create Channel :: Failed to initialize vtable\n");
|
||||
goto FailChannel;
|
||||
}
|
||||
|
||||
/* Now call the channel specific type constructor */
|
||||
Status = Channel->ChannelCreate(Channel);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* This is critical */
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC Create Channel :: Failed channel specific initialization\n");
|
||||
goto FailChannel;
|
||||
}
|
||||
|
||||
/* Finally, mark the channel as active */
|
||||
ChannelSetStatus(Channel, Active);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
FailChannel:
|
||||
/* Destroy the channel and return the failure code */
|
||||
Channel->ChannelDestroy(Channel);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ChannelClose(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
CHECK_PARAMETER(Channel);
|
||||
|
||||
/* Set the channel inactive */
|
||||
ChannelSetStatus(Channel, Inactive);
|
||||
|
||||
/* Set the close event */
|
||||
if (Channel->Flags & SAC_CHANNEL_FLAG_CLOSE_EVENT)
|
||||
{
|
||||
ChannelSetEvent(Channel, CloseEvent);
|
||||
}
|
||||
|
||||
/* Close all the handles */
|
||||
Status = ChannelDereferenceHandles(Channel);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,75 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/concmd.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/concmd.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
PWCHAR GlobalBuffer;
|
||||
ULONG GlobalBufferSize;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DoRebootCommand(IN BOOLEAN Reboot)
|
||||
{
|
||||
LARGE_INTEGER Timeout, TickCount;
|
||||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
SAC_DBG(1, "SAC DoRebootCommand: Entering.\n");
|
||||
|
||||
/* Get the current time now, and setup a timeout in 1 second */
|
||||
KeQueryTickCount(&TickCount);
|
||||
Timeout.QuadPart = TickCount.QuadPart / (10000000 / KeQueryTimeIncrement());
|
||||
|
||||
/* Check if the timeout is small enough */
|
||||
if (Timeout.QuadPart < 60 )
|
||||
{
|
||||
/* Show the prompt */
|
||||
ConMgrSimpleEventMessage(Reboot ?
|
||||
SAC_RESTART_PROMPT : SAC_SHUTDOWN_PROMPT,
|
||||
TRUE);
|
||||
|
||||
/* Do the wait */
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, 0);
|
||||
Timeout.QuadPart = -10000000 * (60 - Timeout.LowPart);
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, &Timeout);
|
||||
}
|
||||
|
||||
/* Do a shutdown or a reboot, based on the request */
|
||||
Status = NtShutdownSystem(Reboot ? ShutdownReboot : ShutdownPowerOff);
|
||||
|
||||
/* Check if anyone in the command channel already allocated this */
|
||||
if (!GlobalBuffer)
|
||||
{
|
||||
/* Allocate it */
|
||||
GlobalBuffer = SacAllocatePool(PAGE_SIZE, GLOBAL_BLOCK_TAG);
|
||||
if (!GlobalBuffer)
|
||||
{
|
||||
/* We need the global buffer, bail out without it*/
|
||||
SacPutSimpleMessage(SAC_OUT_OF_MEMORY_PROMPT);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting (1).\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the size of the buffer */
|
||||
GlobalBufferSize = PAGE_SIZE;
|
||||
}
|
||||
|
||||
/* We came back from a reboot, this doesn't make sense, tell the user */
|
||||
SacPutSimpleMessage(Reboot ? SAC_RESTART_FAIL_PROMPT : SAC_SHUTDOWN_FAIL_PROMPT);
|
||||
swprintf(GlobalBuffer, GetMessage(SAC_FAIL_PROMPT), Status);
|
||||
SacPutString(GlobalBuffer);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC DoRebootCommand: Exiting.\n");
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
GetTListInfo(
|
||||
|
@ -122,14 +179,6 @@ DoLimitMemoryCommand(
|
|||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoRebootCommand(
|
||||
IN BOOLEAN Reboot
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
DoCrashCommand(
|
||||
VOID
|
||||
|
|
|
@ -1,191 +1,541 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/conmgr.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/conmgr.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
DEFINE_GUID(PRIMARY_SAC_CHANNEL_APPLICATION_GUID,
|
||||
0x63D02270,
|
||||
0x8AA4,
|
||||
0x11D5,
|
||||
0xBC, 0xCF, 0x80, 0x6D, 0x61, 0x72, 0x69, 0x6F);
|
||||
|
||||
NTSTATUS
|
||||
ConMgrShutdown(
|
||||
VOID)
|
||||
LONG CurrentChannelRefCount;
|
||||
KMUTEX CurrentChannelLock;
|
||||
|
||||
PSAC_CHANNEL CurrentChannel;
|
||||
PSAC_CHANNEL SacChannel;
|
||||
|
||||
ULONG ExecutePostConsumerCommand;
|
||||
PSAC_CHANNEL ExecutePostConsumerCommandData;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ConMgrSerialPortConsumer(VOID)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
NTSTATUS Status;
|
||||
CHAR Char;
|
||||
SAC_DBG(0x2000, "SAC TimerDpcRoutine: Entering.\n"); //bug
|
||||
|
||||
NTSTATUS
|
||||
ConMgrDisplayFastChannelSwitchingInterface(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
/* Acquire the manager lock and make sure a channel is selected */
|
||||
SacAcquireMutexLock();
|
||||
ASSERT(CurrentChannel);
|
||||
|
||||
NTSTATUS
|
||||
ConMgrSetCurrentChannel(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
/* Read whatever came off the serial port */
|
||||
for (Status = SerialBufferGetChar(&Char);
|
||||
NT_SUCCESS(Status);
|
||||
Status = SerialBufferGetChar(&Char))
|
||||
{
|
||||
/* If nothing came through, bail out */
|
||||
if (Status == STATUS_NO_DATA_DETECTED) break;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConMgrDisplayCurrentChannel(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConMgrAdvanceCurrentChannel(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ConMgrIsWriteEnabled(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
/* We're done, release the lock */
|
||||
SacReleaseMutexLock();
|
||||
SAC_DBG(0x2000, "SAC TimerDpcRoutine: Exiting.\n"); //bug
|
||||
}
|
||||
|
||||
VOID
|
||||
SacPutString(
|
||||
IN PWCHAR String
|
||||
)
|
||||
NTAPI
|
||||
ConMgrWorkerProcessEvents(IN PSAC_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC WorkerProcessEvents: Entering.\n");
|
||||
|
||||
}
|
||||
/* Enter the main loop */
|
||||
while (TRUE)
|
||||
{
|
||||
/* Wait for something to do */
|
||||
KeWaitForSingleObject(&DeviceExtension->Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
|
||||
BOOLEAN
|
||||
SacPutSimpleMessage(
|
||||
IN ULONG MessageIndex
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
/* Consume data off the serial port */
|
||||
ConMgrSerialPortConsumer();
|
||||
switch (ExecutePostConsumerCommand)
|
||||
{
|
||||
case 1:
|
||||
/* A reboot was sent, do it */
|
||||
DoRebootCommand(FALSE);
|
||||
break;
|
||||
|
||||
NTSTATUS
|
||||
ConMgrChannelOWrite(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PVOID WriteBuffer
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
case 2:
|
||||
/* A close was sent, do it */
|
||||
ChanMgrCloseChannel(ExecutePostConsumerCommandData);
|
||||
ChanMgrReleaseChannel(ExecutePostConsumerCommandData);
|
||||
break;
|
||||
|
||||
NTSTATUS
|
||||
ConMgrGetChannelCloseMessage(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN NTSTATUS CloseStatus,
|
||||
OUT PWCHAR OutputBuffer
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
case 3:
|
||||
/* A shutdown was sent, do it */
|
||||
DoRebootCommand(TRUE);
|
||||
break;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConMgrWriteData(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PVOID Buffer,
|
||||
IN ULONG BufferLength
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConMgrFlushData(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ConMgrIsSacChannel(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConMgrInitialize(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConMgrResetCurrentChannel(
|
||||
IN BOOLEAN KeepChannel
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
/* Clear the serial port consumer state */
|
||||
ExecutePostConsumerCommand = 0;
|
||||
ExecutePostConsumerCommandData = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
ConMgrProcessInputLine(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
ConMgrEventMessage(
|
||||
IN PWCHAR EventMessage,
|
||||
IN BOOLEAN LockHeld
|
||||
)
|
||||
NTAPI
|
||||
SacPutString(IN PWCHAR String)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Write the string on the main SAC channel */
|
||||
Status = ChannelOWrite(SacChannel,
|
||||
(PCHAR)String,
|
||||
wcslen(String) * sizeof(WCHAR));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC XmlMgrSacPutString: OWrite failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
ConMgrSimpleEventMessage(
|
||||
IN ULONG MessageIndex,
|
||||
IN BOOLEAN LockHeld
|
||||
)
|
||||
NTAPI
|
||||
SacPutSimpleMessage(IN ULONG MessageIndex)
|
||||
{
|
||||
return FALSE;
|
||||
PWCHAR MessageBuffer;
|
||||
BOOLEAN Result;
|
||||
|
||||
/* Get the message */
|
||||
MessageBuffer = GetMessage(MessageIndex);
|
||||
if (MessageBuffer)
|
||||
{
|
||||
/* Output it */
|
||||
SacPutString(MessageBuffer);
|
||||
Result = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = FALSE;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Result;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConMgrChannelClose(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ConMgrDisplayCurrentChannel(VOID)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN HasRedraw;
|
||||
|
||||
/* Make sure the lock is held */
|
||||
SacAssertMutexLockHeld();
|
||||
|
||||
/* Check if we can redraw */
|
||||
Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedraw);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Enable writes */
|
||||
_InterlockedExchange(&CurrentChannel->WriteEnabled, 1);
|
||||
if (HasRedraw)
|
||||
{
|
||||
/* If we can redraw, set the event */
|
||||
ChannelSetRedrawEvent(CurrentChannel);
|
||||
}
|
||||
|
||||
/* Flush the output */
|
||||
Status = ChannelOFlush(CurrentChannel);
|
||||
}
|
||||
|
||||
/* All done, return the status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ConMgrHandleEvent(
|
||||
IN ULONG EventCode,
|
||||
IN PSAC_CHANNEL Channel,
|
||||
OUT PVOID Data
|
||||
)
|
||||
NTAPI
|
||||
ConMgrWriteData(IN PSAC_CHANNEL Channel,
|
||||
IN PVOID Buffer,
|
||||
IN ULONG BufferLength)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
LARGE_INTEGER Interval;
|
||||
|
||||
/* Loop up to 32 times */
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
/* Attempt sending the data */
|
||||
Status = HeadlessDispatch(HeadlessCmdPutData, Buffer, BufferLength, NULL, NULL);
|
||||
if (Status != STATUS_UNSUCCESSFUL) break;
|
||||
|
||||
/* Sending the data on the port failed, wait a second... */
|
||||
Interval.HighPart = -1;
|
||||
Interval.LowPart = -100000;
|
||||
KeDelayExecutionThread(KernelMode, FALSE, &Interval);
|
||||
}
|
||||
|
||||
/* After 32 attempts it should really have worked... */
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrFlushData(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
/* Nothing to do */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ConMgrIsSacChannel(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
/* Check which channel is active */
|
||||
return Channel == SacChannel;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ConMgrIsWriteEnabled(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
/* If the current channel is active, allow writes */
|
||||
return ChannelIsEqual(Channel, &CurrentChannel->ChannelId);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrInitialize(VOID)
|
||||
{
|
||||
PWCHAR pcwch;
|
||||
PSAC_CHANNEL FoundChannel;
|
||||
SAC_CHANNEL_ATTRIBUTES SacChannelAttributes;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Initialize the connection manager lock */
|
||||
SacInitializeMutexLock();
|
||||
SacAcquireMutexLock();
|
||||
|
||||
/* Setup the attributes for the raw SAC channel */
|
||||
RtlZeroMemory(&SacChannelAttributes, sizeof(SacChannelAttributes));
|
||||
SacChannelAttributes.ChannelType = Raw;
|
||||
|
||||
/* Get the right name for it */
|
||||
pcwch = GetMessage(SAC_CHANNEL_NAME);
|
||||
ASSERT(pcwch);
|
||||
wcsncpy(SacChannelAttributes.NameBuffer, pcwch, SAC_CHANNEL_NAME_SIZE);
|
||||
SacChannelAttributes.NameBuffer[SAC_CHANNEL_NAME_SIZE] = ANSI_NULL;
|
||||
|
||||
/* Get the right description for it */
|
||||
pcwch = GetMessage(SAC_CHANNEL_DESCRIPTION);
|
||||
ASSERT(pcwch);
|
||||
wcsncpy(SacChannelAttributes.DescriptionBuffer, pcwch, SAC_CHANNEL_DESCRIPTION_SIZE);
|
||||
SacChannelAttributes.DescriptionBuffer[SAC_CHANNEL_DESCRIPTION_SIZE] = ANSI_NULL;
|
||||
|
||||
/* Set all the right flags */
|
||||
SacChannelAttributes.Flag = SAC_CHANNEL_FLAG_APPLICATION | SAC_CHANNEL_FLAG_INTERNAL;
|
||||
SacChannelAttributes.CloseEvent = NULL;
|
||||
SacChannelAttributes.HasNewDataEvent = NULL;
|
||||
SacChannelAttributes.LockEvent = NULL;
|
||||
SacChannelAttributes.RedrawEvent = NULL;
|
||||
SacChannelAttributes.ChannelId = PRIMARY_SAC_CHANNEL_APPLICATION_GUID;
|
||||
|
||||
/* Now create it */
|
||||
Status = ChanMgrCreateChannel(&SacChannel, &SacChannelAttributes);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Try to get it back */
|
||||
Status = ChanMgrGetByHandle(SacChannel->ChannelId, &FoundChannel);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Set it as the current and SAC channel */
|
||||
SacChannel = CurrentChannel = FoundChannel;
|
||||
|
||||
/* Diasable writes for now and clear the display */
|
||||
_InterlockedExchange(&FoundChannel->WriteEnabled, FALSE);
|
||||
Status = HeadlessDispatch(HeadlessCmdClearDisplay, NULL, 0, NULL, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC ConMgrInitialize: Failed dispatch\n");
|
||||
}
|
||||
|
||||
/* Display the initial prompt */
|
||||
SacPutSimpleMessage(SAC_NEWLINE);
|
||||
SacPutSimpleMessage(SAC_INIT_STATUS);
|
||||
SacPutSimpleMessage(SAC_NEWLINE);
|
||||
SacPutSimpleMessage(SAC_PROMPT);
|
||||
|
||||
/* Display the current channel */
|
||||
ConMgrDisplayCurrentChannel();
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the channel lock */
|
||||
SacReleaseMutexLock();
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
ConMgrWorkerProcessEvents(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
ConMgrEventMessage(IN PWCHAR EventMessage,
|
||||
IN BOOLEAN LockHeld)
|
||||
{
|
||||
/* Acquire the current channel lock if needed */
|
||||
if (!LockHeld) SacAcquireMutexLock();
|
||||
|
||||
/* Send out the event message */
|
||||
SacPutSimpleMessage(2);
|
||||
SacPutString(EventMessage);
|
||||
SacPutSimpleMessage(3);
|
||||
|
||||
/* Release the current channel lock if needed */
|
||||
if (!LockHeld) SacReleaseMutexLock();
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ConMgrSimpleEventMessage(IN ULONG MessageIndex,
|
||||
IN BOOLEAN LockHeld)
|
||||
{
|
||||
PWCHAR MessageBuffer;
|
||||
BOOLEAN Result;
|
||||
|
||||
/* Get the message to send out */
|
||||
MessageBuffer = GetMessage(MessageIndex);
|
||||
if (MessageBuffer)
|
||||
{
|
||||
/* Send it */
|
||||
ConMgrEventMessage(MessageBuffer, LockHeld);
|
||||
Result = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It doesn't exist, fail */
|
||||
Result = FALSE;
|
||||
}
|
||||
|
||||
/* Return if the message was sent or not */
|
||||
return Result;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrDisplayFastChannelSwitchingInterface(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
/* FIXME: TODO */
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrSetCurrentChannel(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
BOOLEAN HasRedrawEvent;
|
||||
|
||||
/* Make sure the lock is held */
|
||||
SacAssertMutexLockHeld();
|
||||
|
||||
/* Check if we have a redraw event */
|
||||
Status = ChannelHasRedrawEvent(CurrentChannel, &HasRedrawEvent);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Clear it */
|
||||
if (HasRedrawEvent) ChannelClearRedrawEvent(CurrentChannel);
|
||||
|
||||
/* Disable writes on the current channel */
|
||||
_InterlockedExchange(&CurrentChannel->WriteEnabled, 0);
|
||||
|
||||
/* Release the current channel */
|
||||
Status = ChanMgrReleaseChannel(CurrentChannel);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Set the new channel and also disable writes on it */
|
||||
CurrentChannel = Channel;
|
||||
_InterlockedExchange(&Channel->WriteEnabled, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrResetCurrentChannel(IN BOOLEAN KeepChannel)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PSAC_CHANNEL Channel;
|
||||
|
||||
/* Make sure the lock is held */
|
||||
SacAssertMutexLockHeld();
|
||||
|
||||
/* Get the current SAC channel */
|
||||
Status = ChanMgrGetByHandle(SacChannel->ChannelId, &Channel);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Set this as the current SAC channel*/
|
||||
SacChannel = Channel;
|
||||
Status = ConMgrSetCurrentChannel(Channel);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Check if the caller wants to switch or not */
|
||||
if (KeepChannel)
|
||||
{
|
||||
/* Nope, keep the same channel */
|
||||
Status = ConMgrDisplayCurrentChannel();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Yep, show the switching interface */
|
||||
Status = ConMgrDisplayFastChannelSwitchingInterface(CurrentChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrChannelClose(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
/* Check if we're in the right channel */
|
||||
if (ConMgrIsWriteEnabled(Channel))
|
||||
{
|
||||
/* Yep, reset it */
|
||||
Status = ConMgrResetCurrentChannel(FALSE);
|
||||
ASSERT(NT_SUCCESS(Status));
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrShutdown(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Check if we have a SAC channel */
|
||||
if (SacChannel)
|
||||
{
|
||||
/* Close it */
|
||||
Status = ChannelClose(SacChannel);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC ConMgrShutdown: failed closing SAC channel.\n");
|
||||
}
|
||||
|
||||
/* No longer have one */
|
||||
SacChannel = NULL;
|
||||
}
|
||||
|
||||
/* Check if we have a current channel */
|
||||
if (CurrentChannel)
|
||||
{
|
||||
/* Release it */
|
||||
Status = ChanMgrReleaseChannel(CurrentChannel);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC ConMgrShutdown: failed releasing current channel\n");
|
||||
}
|
||||
|
||||
/* No longer have one */
|
||||
CurrentChannel = NULL;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrAdvanceCurrentChannel(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG Index;
|
||||
PSAC_CHANNEL Channel;
|
||||
|
||||
/* Should always be called with the lock held */
|
||||
SacAssertMutexLockHeld();
|
||||
|
||||
/* Get the next active channel */
|
||||
Status = ChanMgrGetNextActiveChannel(CurrentChannel, &Index, &Channel);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Set it as the new channel */
|
||||
Status = ConMgrSetCurrentChannel(Channel);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Let the user switch to it */
|
||||
Status = ConMgrDisplayFastChannelSwitchingInterface(Channel);
|
||||
}
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrChannelOWrite(IN PSAC_CHANNEL Channel,
|
||||
IN PVOID WriteBuffer)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Do the write with the lock held */
|
||||
SacAcquireMutexLock();
|
||||
Status = STATUS_NOT_IMPLEMENTED;// ChannelOWrite(Channel, WriteBuffer + 24, *(WriteBuffer + 20));
|
||||
SacReleaseMutexLock();
|
||||
|
||||
/* Return back to the caller */
|
||||
ASSERT(NT_SUCCESS(Status) || Status == STATUS_NOT_FOUND);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrGetChannelCloseMessage(IN PSAC_CHANNEL Channel,
|
||||
IN NTSTATUS CloseStatus,
|
||||
OUT PWCHAR OutputBuffer)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ConMgrProcessInputLine(VOID)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ConMgrHandleEvent(IN ULONG EventCode,
|
||||
IN PSAC_CHANNEL Channel,
|
||||
OUT PVOID Data)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,58 +1,502 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/data.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/data.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
ULONG SACDebug;
|
||||
ULONG SACDebug = 0xFFFFFFFF;
|
||||
BOOLEAN CommandConsoleLaunchingEnabled;
|
||||
BOOLEAN GlobalDataInitialized;
|
||||
KMUTEX SACCMDEventInfoMutex;
|
||||
BOOLEAN IoctlSubmitted;
|
||||
ULONG ProcessingType;
|
||||
PKEVENT SACEvent;
|
||||
HANDLE SACEventHandle;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
FreeGlobalData(
|
||||
VOID
|
||||
)
|
||||
NTAPI
|
||||
WorkerProcessEvents(IN PSAC_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
|
||||
/* Call the worker function */
|
||||
return ConMgrWorkerProcessEvents(DeviceExtension);
|
||||
}
|
||||
|
||||
VOID
|
||||
FreeDeviceData(
|
||||
IN PDEVICE_OBJECT DeviceObject
|
||||
)
|
||||
NTAPI
|
||||
WorkerThreadStartUp(IN PVOID Context)
|
||||
{
|
||||
|
||||
/* Call the worker function */
|
||||
WorkerProcessEvents((PSAC_DEVICE_EXTENSION)Context);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
WorkerThreadStartUp(
|
||||
IN PVOID Context
|
||||
)
|
||||
NTAPI
|
||||
BuildDeviceAcl(OUT PACL* Dacl)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
/* TODO */
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CreateDeviceSecurityDescriptor(IN PDEVICE_OBJECT *DeviceObject)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
BOOLEAN MemoryAllocated = FALSE;
|
||||
PACL Dacl = NULL;
|
||||
PVOID ObjectSecurityDescriptor = NULL;
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC CreateDeviceSecurityDescriptor: Entering.\n");
|
||||
|
||||
/* Get the current SD of the device object */
|
||||
Status = ObGetObjectSecurity(*DeviceObject, &SecurityDescriptor, &MemoryAllocated);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC: Unable to get security descriptor, error: %x\n", Status);
|
||||
NT_ASSERT(MemoryAllocated == FALSE);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC CreateDeviceSecurityDescriptor: Exiting with status 0x%x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Build a DACL for it */
|
||||
Status = BuildDeviceAcl(&Dacl);
|
||||
if (Status >= 0)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC CreateDeviceSecurityDescriptor : Unable to create Raw ACL, error : %x\n", Status);
|
||||
goto CleanupPath;
|
||||
}
|
||||
|
||||
CleanupPath:
|
||||
/* Release the SD we queried */
|
||||
ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated);
|
||||
|
||||
/* Free anything else we may have allocated */
|
||||
if (ObjectSecurityDescriptor) ExFreePool(ObjectSecurityDescriptor);
|
||||
if (Dacl) SacFreePool(Dacl);
|
||||
|
||||
/* All done */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC CreateDeviceSecurityDescriptor: Exiting with status 0x%x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
FreeGlobalData(VOID)
|
||||
{
|
||||
UNICODE_STRING SymbolicLink;
|
||||
SAC_DBG(1, "SAC FreeGlobalData: Entering.\n");
|
||||
|
||||
/* Only free if we allocated */
|
||||
if (GlobalDataInitialized)
|
||||
{
|
||||
/* Close the SAC event if we had created one */
|
||||
if (SACEvent)
|
||||
{
|
||||
ZwClose(SACEventHandle);
|
||||
SACEvent = NULL;
|
||||
}
|
||||
|
||||
/* Destroy the cached messages */
|
||||
TearDownGlobalMessageTable();
|
||||
|
||||
/* Delete the Win32 symbolic link */
|
||||
RtlInitUnicodeString(&SymbolicLink, L"\\DosDevices\\SAC");
|
||||
IoDeleteSymbolicLink(&SymbolicLink);
|
||||
|
||||
/* Tear down connections */
|
||||
ConMgrShutdown();
|
||||
|
||||
/* Tear down channels */
|
||||
ChanMgrShutdown();
|
||||
|
||||
/* Free the serial port buffer */
|
||||
if (SerialPortBuffer) SacFreePool(SerialPortBuffer);
|
||||
|
||||
/* Free cached machine information */
|
||||
FreeMachineInformation();
|
||||
|
||||
/* Cleanup the custom heap allocator */
|
||||
FreeMemoryManagement();
|
||||
|
||||
/* We're back to a virgin state */
|
||||
GlobalDataInitialized = FALSE;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
SAC_DBG(1, "SAC FreeGlobalData: Exiting.\n");
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
FreeDeviceData(IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PSAC_DEVICE_EXTENSION DeviceExtension;
|
||||
NTSTATUS Status;
|
||||
KIRQL OldIrql;
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC FreeDeviceData: Entering.\n");
|
||||
|
||||
/* Get the device extension and see how far we had gotten */
|
||||
DeviceExtension = (PSAC_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
if ((GlobalDataInitialized) && (DeviceExtension->Initialized))
|
||||
{
|
||||
/* Attempt to rundown while holding the lock */
|
||||
KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql);
|
||||
while (DeviceExtension->RundownInProgress)
|
||||
{
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC FreeDeviceData: Waiting....\n");
|
||||
|
||||
/* Initiate and wait for rundown */
|
||||
KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, 0);
|
||||
KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql);
|
||||
Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
|
||||
/* Re-acquire the lock and check if rundown is done */
|
||||
KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now set the rundown flag while we cancel the timer */
|
||||
DeviceExtension->RundownInProgress = TRUE;
|
||||
KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql);
|
||||
|
||||
/* Cancel it */
|
||||
KeCancelTimer(&DeviceExtension->Timer);
|
||||
|
||||
/* Reacquire the lock*/
|
||||
KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql);
|
||||
DeviceExtension->RundownInProgress = FALSE;
|
||||
|
||||
/* Now do the last rundown attempt, we should be the only ones here */
|
||||
KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, 0);
|
||||
KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql);
|
||||
KeSetEvent(&DeviceExtension->Event, DeviceExtension->PriorityBoost, 0);
|
||||
Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
|
||||
/* We no longer care about shutdown */
|
||||
IoUnregisterShutdownNotification(DeviceObject);
|
||||
|
||||
/* We are now fully uninitialized */
|
||||
KeAcquireSpinLock(&DeviceExtension->Lock, &OldIrql);
|
||||
DeviceExtension->Initialized = FALSE;
|
||||
KeReleaseSpinLock(&DeviceExtension->Lock, OldIrql);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC FreeDeviceData: Exiting.\n");
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
InitializeDeviceData(
|
||||
IN PDEVICE_OBJECT DeviceObject
|
||||
)
|
||||
NTAPI
|
||||
InitializeDeviceData(IN PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
return FALSE;
|
||||
PSAC_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
BOOLEAN EnableData;
|
||||
ULONG PriorityValue;
|
||||
NTSTATUS Status;
|
||||
LARGE_INTEGER DueTime;
|
||||
PWCHAR Message;
|
||||
PAGED_CODE();
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n");
|
||||
|
||||
/* If we already did this, bail out */
|
||||
if (DeviceExtension->Initialized) goto SuccessExit;
|
||||
|
||||
/* Setup the DO flags */
|
||||
DeviceObject->Flags |= DO_DIRECT_IO;
|
||||
DeviceObject->StackSize = 16;
|
||||
|
||||
/* Setup the device extension */
|
||||
DeviceExtension->DeviceObject = DeviceObject;
|
||||
DeviceExtension->PriorityBoost = IO_SERIAL_INCREMENT;
|
||||
DeviceExtension->PriorityFail = 0;
|
||||
DeviceExtension->RundownInProgress = 0;
|
||||
|
||||
/* Initialize locks, events, timers, DPCs, etc... */
|
||||
KeInitializeTimer(&DeviceExtension->Timer);
|
||||
KeInitializeDpc(&DeviceExtension->Dpc, TimerDpcRoutine, DeviceExtension);
|
||||
KeInitializeSpinLock(&DeviceExtension->Lock);
|
||||
KeInitializeEvent(&DeviceExtension->Event, SynchronizationEvent, 0);
|
||||
InitializeListHead(&DeviceExtension->List);
|
||||
|
||||
/* Attempt to enable HDL support */
|
||||
EnableData = TRUE;
|
||||
Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
|
||||
&EnableData,
|
||||
sizeof(EnableData),
|
||||
NULL,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Bail out if we couldn't even get this far */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (1) with status FALSE\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Remember which process we started in */
|
||||
DeviceExtension->Process = IoGetCurrentProcess();
|
||||
|
||||
/* Protect the device against non-admins */
|
||||
Status = CreateDeviceSecurityDescriptor(&DeviceExtension->DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Write down why we failed */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (2) with status FALSE\n");
|
||||
|
||||
/* Disable the HDL terminal on failure */
|
||||
EnableData = FALSE;
|
||||
Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
|
||||
&EnableData,
|
||||
sizeof(EnableData),
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n");
|
||||
|
||||
/* Bail out */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create the worker thread */
|
||||
Status = PsCreateSystemThread(&DeviceExtension->WorkerThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
WorkerThreadStartUp,
|
||||
DeviceExtension);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Write down why we failed */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (3) with status FALSE\n");
|
||||
|
||||
/* Disable the HDL terminal on failure */
|
||||
EnableData = FALSE;
|
||||
Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
|
||||
&EnableData,
|
||||
sizeof(EnableData),
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n");
|
||||
|
||||
/* Bail out */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Set the priority of our thread to highest */
|
||||
PriorityValue = HIGH_PRIORITY;
|
||||
Status = NtSetInformationThread(DeviceExtension->WorkerThreadHandle,
|
||||
ThreadPriority,
|
||||
&PriorityValue,
|
||||
sizeof(PriorityValue));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* For debugging, write down why we failed */
|
||||
SAC_DBG(1, "Exiting (6) with status FALSE\n");
|
||||
DeviceExtension->PriorityFail = TRUE;
|
||||
|
||||
/* Initialize rundown and wait for the thread to do it */
|
||||
KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, 0);
|
||||
KeSetEvent(&DeviceExtension->Event, DeviceExtension->PriorityBoost, 0);
|
||||
Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
ASSERT(Status == STATUS_SUCCESS);
|
||||
|
||||
/* Disable the HDL terminal on failure */
|
||||
EnableData = FALSE;
|
||||
Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
|
||||
&EnableData,
|
||||
sizeof(EnableData),
|
||||
NULL,
|
||||
0);
|
||||
if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n");
|
||||
|
||||
/* Bail out */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* The first "packet" is the machine information in XML... */
|
||||
Status = TranslateMachineInformationXML(&Message, NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Go ahead and send it */
|
||||
UTF8EncodeAndSend(L"<?xml version=\"1.0\"?>\r\n");
|
||||
UTF8EncodeAndSend(Message);
|
||||
|
||||
/* Free the temporary buffer */
|
||||
SacFreePool(Message);
|
||||
}
|
||||
|
||||
/* Finally, initialize the I/O Manager */
|
||||
Status = ConMgrInitialize();
|
||||
if (!NT_SUCCESS(Status)) return FALSE;
|
||||
|
||||
/* Set the timer. Once this is done, the device is initialized */
|
||||
DueTime.QuadPart = -4000;
|
||||
KeSetTimerEx(&DeviceExtension->Timer, DueTime, 4, &DeviceExtension->Dpc);
|
||||
DeviceExtension->Initialized = TRUE;
|
||||
|
||||
SuccessExit:
|
||||
/* Success path -- everything worked */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status TRUE\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
InitializeGlobalData(
|
||||
IN PUNICODE_STRING RegistryPath,
|
||||
IN PDRIVER_OBJECT DriverObject
|
||||
)
|
||||
NTAPI
|
||||
InitializeGlobalData(IN PUNICODE_STRING RegistryPath,
|
||||
IN PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
return FALSE;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING LinkName;
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING EventName;
|
||||
PAGED_CODE();
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n");
|
||||
|
||||
/* If we already did this, bail out */
|
||||
if (!GlobalDataInitialized) goto SuccessExit;
|
||||
|
||||
/* Setup the symbolic link for Win32 support */
|
||||
RtlInitUnicodeString(&LinkName, L"\\DosDevices\\SAC");
|
||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\SAC");
|
||||
Status = IoCreateSymbolicLink(&LinkName, &DeviceName);
|
||||
if (!NT_SUCCESS(Status)) return FALSE;
|
||||
|
||||
/* Initialize the internal heap manager */
|
||||
if (!InitializeMemoryManagement())
|
||||
{
|
||||
IoDeleteSymbolicLink(&LinkName);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status FALSE\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Preload the messages in memory */
|
||||
Status = PreloadGlobalMessageTable(DriverObject->DriverStart);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
IoDeleteSymbolicLink(&LinkName);
|
||||
SAC_DBG(SAC_DBG_INIT, "unable to pre-load message table: %X\n", Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check if the administrator enabled this */
|
||||
Status = GetCommandConsoleLaunchingPermission(&CommandConsoleLaunchingEnabled);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Is it enabled? */
|
||||
if (CommandConsoleLaunchingEnabled)
|
||||
{
|
||||
/* Set the service start type to the correct value */
|
||||
Status = ImposeSacCmdServiceStartTypePolicy();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "failed ImposeSacCmdServiceStartTypePolicy: %X\n", Status);
|
||||
}
|
||||
}
|
||||
|
||||
/* We're going to keep going with the default */
|
||||
SAC_DBG(SAC_DBG_INIT, "failed GetCommandConsoleLaunchingPermission: %X\n", Status);
|
||||
}
|
||||
|
||||
/* Allocate the UTF-8 Conversion Buffer */
|
||||
Utf8ConversionBuffer = SacAllocatePool(Utf8ConversionBufferSize, GLOBAL_BLOCK_TAG);
|
||||
if (!Utf8ConversionBuffer)
|
||||
{
|
||||
/* Handle failure case */
|
||||
TearDownGlobalMessageTable();
|
||||
IoDeleteSymbolicLink(&LinkName);
|
||||
SAC_DBG(SAC_DBG_INIT, "unable to allocate memory for UTF8 translation\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize the channel manager */
|
||||
Status = ChanMgrInitialize();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Handle failure case */
|
||||
SacFreePool(Utf8ConversionBuffer);
|
||||
TearDownGlobalMessageTable();
|
||||
IoDeleteSymbolicLink(&LinkName);
|
||||
SAC_DBG(SAC_DBG_INIT, "Failed to create SAC Channel\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Allocate the serial port buffer */
|
||||
SerialPortBuffer = SacAllocatePool(SAC_SERIAL_PORT_BUFFER_SIZE, GLOBAL_BLOCK_TAG);
|
||||
if (!SerialPortBuffer)
|
||||
{
|
||||
/* Handle failure case */
|
||||
SacFreePool(Utf8ConversionBuffer);
|
||||
TearDownGlobalMessageTable();
|
||||
IoDeleteSymbolicLink(&LinkName);
|
||||
SAC_DBG(SAC_DBG_INIT, "Failed to allocate Serial Port Buffer\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Zero it out */
|
||||
RtlZeroMemory(SerialPortBuffer, SAC_SERIAL_PORT_BUFFER_SIZE);
|
||||
|
||||
/* Initialize command events. After this, driver data is good to go */
|
||||
KeInitializeMutex(&SACCMDEventInfoMutex, FALSE);
|
||||
InitializeCmdEventInfo();
|
||||
GlobalDataInitialized = TRUE;
|
||||
ProcessingType = 0;
|
||||
IoctlSubmitted = 0;
|
||||
|
||||
/* Create the SAC event */
|
||||
RtlInitUnicodeString(&EventName, L"\\SACEvent");
|
||||
SACEvent = IoCreateSynchronizationEvent(&EventName, &SACEventHandle);
|
||||
if (!SACEvent)
|
||||
{
|
||||
/* Handle failure case */
|
||||
SacFreePool(Utf8ConversionBuffer);
|
||||
TearDownGlobalMessageTable();
|
||||
IoDeleteSymbolicLink(&LinkName);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with event NULL\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Cache machine information */
|
||||
InitializeMachineInformation();
|
||||
|
||||
/* Register it */
|
||||
Status = RegisterBlueScreenMachineInformation();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Handle failure case */
|
||||
SacFreePool(Utf8ConversionBuffer);
|
||||
TearDownGlobalMessageTable();
|
||||
IoDeleteSymbolicLink(&LinkName);
|
||||
SAC_DBG(SAC_DBG_INIT, "Failed to register blue screen machine info\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SuccessExit:
|
||||
/* Success path -- everything worked */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status TRUE\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,88 +1,90 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/dispatch.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/dispatch.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DispatchDeviceControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
)
|
||||
DispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
DispatchShutdownControl(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
)
|
||||
NTAPI
|
||||
DispatchShutdownControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
DispatchCreate(
|
||||
IN PSAC_DEVICE_EXTENSION DeviceExtension,
|
||||
IN PIRP Irp
|
||||
)
|
||||
NTAPI
|
||||
DispatchCreate(IN PSAC_DEVICE_EXTENSION DeviceExtension,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
DispatchClose(
|
||||
IN PSAC_DEVICE_EXTENSION DeviceExtension,
|
||||
IN PIRP Irp
|
||||
)
|
||||
NTAPI
|
||||
DispatchClose(IN PSAC_DEVICE_EXTENSION DeviceExtension,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
Dispatch(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp
|
||||
)
|
||||
NTAPI
|
||||
Dispatch(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
WorkerProcessEvents(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
TimerDpcRoutine(
|
||||
IN PKDPC Dpc,
|
||||
IN PVOID DeferredContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2
|
||||
)
|
||||
NTAPI
|
||||
TimerDpcRoutine(IN PKDPC Dpc,
|
||||
IN PVOID DeferredContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
UnloadHandler(
|
||||
IN PDRIVER_OBJECT DriverObject
|
||||
)
|
||||
NTAPI
|
||||
UnloadHandler(IN PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject, NextDevice;
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC UnloadHandler: Entering.\n");
|
||||
|
||||
/* Go overy ever device part of the driver */
|
||||
DeviceObject = DriverObject->DeviceObject;
|
||||
while (DeviceObject)
|
||||
{
|
||||
/* Free and delete the information about this device */
|
||||
NextDevice = DeviceObject->NextDevice;
|
||||
FreeDeviceData(DeviceObject);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
|
||||
/* Move on to the next one */
|
||||
DeviceObject = NextDevice;
|
||||
}
|
||||
|
||||
/* Free the driver data and exit */
|
||||
FreeGlobalData();
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC UnloadHandler: Exiting.\n");
|
||||
}
|
||||
|
|
|
@ -1,94 +1,94 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/init.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/init.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
DriverEntry(
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath
|
||||
)
|
||||
DriverEntry(IN PDRIVER_OBJECT DriverObject,
|
||||
IN PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
HEADLESS_RSP_QUERY_INFO HeadlessInformation;
|
||||
ULONG InfoSize;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING DriverName;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PSAC_DEVICE_EXTENSION DeviceExtension;
|
||||
PAGED_CODE();
|
||||
HEADLESS_RSP_QUERY_INFO HeadlessInformation;
|
||||
ULONG InfoSize = sizeof(HeadlessInformation);
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING DriverName;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PSAC_DEVICE_EXTENSION DeviceExtension;
|
||||
PAGED_CODE();
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n");
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n");
|
||||
/* Check if EMS is enabled in the kernel */
|
||||
HeadlessDispatch(HeadlessCmdQueryInformation,
|
||||
NULL,
|
||||
0,
|
||||
&HeadlessInformation,
|
||||
&InfoSize);
|
||||
if ((HeadlessInformation.Serial.TerminalType != HeadlessUndefinedPortType) &&
|
||||
((HeadlessInformation.Serial.TerminalType != HeadlessSerialPort) ||
|
||||
(HeadlessInformation.Serial.TerminalAttached)))
|
||||
{
|
||||
/* It is, so create the device */
|
||||
RtlInitUnicodeString(&DriverName, L"\\Device\\SAC");
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(SAC_DEVICE_EXTENSION),
|
||||
&DriverName,
|
||||
FILE_DEVICE_UNKNOWN,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&DeviceObject);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Setup the device extension */
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
DeviceExtension->Initialized = FALSE;
|
||||
|
||||
HeadlessDispatch(
|
||||
HeadlessCmdQueryInformation,
|
||||
NULL,
|
||||
0,
|
||||
&HeadlessInformation,
|
||||
&InfoSize
|
||||
);
|
||||
if ((HeadlessInformation.Serial.TerminalType != HeadlessUndefinedPortType) &&
|
||||
((HeadlessInformation.Serial.TerminalType != HeadlessSerialPort) ||
|
||||
(HeadlessInformation.Serial.TerminalAttached)))
|
||||
{
|
||||
RtlInitUnicodeString(&DriverName, L"\\Device\\SAC");
|
||||
/* Initialize the driver object */
|
||||
RtlFillMemoryUlong(DriverObject->MajorFunction,
|
||||
RTL_NUMBER_OF(DriverObject->MajorFunction),
|
||||
(ULONG_PTR)Dispatch);
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DispatchShutdownControl;
|
||||
DriverObject->FastIoDispatch = NULL;
|
||||
DriverObject->DriverUnload = UnloadHandler;
|
||||
|
||||
Status = IoCreateDevice(
|
||||
DriverObject,
|
||||
sizeof(SAC_DEVICE_EXTENSION),
|
||||
&DriverName,
|
||||
FILE_DEVICE_UNKNOWN,
|
||||
FILE_DEVICE_SECURE_OPEN,
|
||||
FALSE,
|
||||
&DeviceObject
|
||||
);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
DeviceExtension->Initialized = FALSE;
|
||||
/* Initialize driver data */
|
||||
if (InitializeGlobalData(RegistryPath, DriverObject))
|
||||
{
|
||||
/* Initialize device data */
|
||||
if (InitializeDeviceData(DeviceObject))
|
||||
{
|
||||
/* We're all good, register a shutdown notification */
|
||||
IoRegisterShutdownNotification(DeviceObject);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
RtlFillMemoryUlong(
|
||||
DriverObject->MajorFunction,
|
||||
sizeof(DriverObject->MajorFunction) / sizeof(PVOID),
|
||||
(ULONG_PTR)Dispatch);
|
||||
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
|
||||
DispatchDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =
|
||||
DispatchShutdownControl;
|
||||
DriverObject->FastIoDispatch = NULL;
|
||||
DriverObject->DriverUnload = UnloadHandler;
|
||||
/* One of the initializations failed, bail out */
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Print a debug statement if enabled */
|
||||
SAC_DBG(SAC_DBG_INIT, "unable to create device object: %X\n", Status);
|
||||
}
|
||||
|
||||
if (InitializeGlobalData(RegistryPath, DriverObject))
|
||||
{
|
||||
if (InitializeDeviceData(DeviceObject))
|
||||
{
|
||||
IoRegisterShutdownNotification(DeviceObject);
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
/* Free any data we may have allocated and exit with failure */
|
||||
FreeGlobalData();
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status 0x%x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "unable to create device object: %X\n", Status);
|
||||
}
|
||||
|
||||
FreeGlobalData();
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status 0x%x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return STATUS_PORT_DISCONNECTED;
|
||||
/* EMS is not enabled */
|
||||
return STATUS_PORT_DISCONNECTED;
|
||||
}
|
||||
|
|
|
@ -1,108 +1,112 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/memory.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/memory.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
LONG TotalFrees, TotalBytesFreed, TotalAllocations, TotalBytesAllocated;
|
||||
KSPIN_LOCK MemoryLock;
|
||||
PSAC_MEMORY_LIST GlobalMemoryList;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
InitializeMemoryManagement(VOID)
|
||||
{
|
||||
PSAC_MEMORY_ENTRY Entry;
|
||||
PSAC_MEMORY_ENTRY Entry;
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
|
||||
/* Allocate a nonpaged heap for us to use */
|
||||
GlobalMemoryList = ExAllocatePoolWithTagPriority(NonPagedPool,
|
||||
SAC_MEMORY_LIST_SIZE,
|
||||
INITIAL_BLOCK_TAG,
|
||||
HighPoolPriority);
|
||||
if (GlobalMemoryList)
|
||||
{
|
||||
/* Initialize a lock for it */
|
||||
KeInitializeSpinLock(&MemoryLock);
|
||||
|
||||
GlobalMemoryList = ExAllocatePoolWithTagPriority(
|
||||
NonPagedPool,
|
||||
SAC_MEMORY_LIST_SIZE,
|
||||
INITIAL_BLOCK_TAG,
|
||||
HighPoolPriority);
|
||||
if (GlobalMemoryList)
|
||||
{
|
||||
KeInitializeSpinLock(&MemoryLock);
|
||||
/* Initialize the head of the list */
|
||||
GlobalMemoryList->Signature = GLOBAL_MEMORY_SIGNATURE;
|
||||
GlobalMemoryList->LocalDescriptor = (PSAC_MEMORY_ENTRY)(GlobalMemoryList + 1);
|
||||
GlobalMemoryList->Size = SAC_MEMORY_LIST_SIZE - sizeof(SAC_MEMORY_LIST);
|
||||
GlobalMemoryList->Next = NULL;
|
||||
|
||||
GlobalMemoryList->Signature = GLOBAL_MEMORY_SIGNATURE;
|
||||
GlobalMemoryList->LocalDescriptor =
|
||||
(PSAC_MEMORY_ENTRY)(GlobalMemoryList + 1);
|
||||
GlobalMemoryList->Size = SAC_MEMORY_LIST_SIZE - sizeof(SAC_MEMORY_LIST);
|
||||
/* Initialize the first free entry */
|
||||
Entry = GlobalMemoryList->LocalDescriptor;
|
||||
Entry->Signature = LOCAL_MEMORY_SIGNATURE;
|
||||
Entry->Tag = FREE_POOL_TAG;
|
||||
Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY);
|
||||
|
||||
Entry = GlobalMemoryList->LocalDescriptor;
|
||||
Entry->Signature = LOCAL_MEMORY_SIGNATURE;
|
||||
Entry->Tag = FREE_POOL_TAG;
|
||||
Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY);
|
||||
/* All done */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n");
|
||||
return FALSE;
|
||||
/* No pool available to manage our heap */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
FreeMemoryManagement(
|
||||
VOID
|
||||
)
|
||||
NTAPI
|
||||
FreeMemoryManagement(VOID)
|
||||
{
|
||||
PSAC_MEMORY_LIST Next;
|
||||
KIRQL OldIrql;
|
||||
PSAC_MEMORY_LIST Next;
|
||||
KIRQL OldIrql;
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
|
||||
/* Acquire the memory lock while freeing the list(s) */
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
while (GlobalMemoryList)
|
||||
{
|
||||
ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
|
||||
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
while (GlobalMemoryList)
|
||||
{
|
||||
ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
|
||||
/* While outisde of the lock, save the next list and free this one */
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
Next = GlobalMemoryList->Next;
|
||||
ExFreePoolWithTag(GlobalMemoryList, 0);
|
||||
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
/* Reacquire the lock and see if there was another list to free */
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
GlobalMemoryList = Next;
|
||||
}
|
||||
|
||||
Next = GlobalMemoryList->Next;
|
||||
|
||||
ExFreePoolWithTag(GlobalMemoryList, 0);
|
||||
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
GlobalMemoryList = Next;
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n");
|
||||
/* All done */
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n");
|
||||
}
|
||||
|
||||
PVOID
|
||||
MyAllocatePool(
|
||||
IN SIZE_T PoolSize,
|
||||
IN ULONG Tag,
|
||||
IN PCHAR File,
|
||||
IN ULONG Line
|
||||
)
|
||||
NTAPI
|
||||
MyAllocatePool(IN SIZE_T PoolSize,
|
||||
IN ULONG Tag,
|
||||
IN PCHAR File,
|
||||
IN ULONG Line)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor;
|
||||
PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor;
|
||||
ULONG GlobalSize, ActualSize;
|
||||
PVOID Buffer;
|
||||
KIRQL OldIrql;
|
||||
PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor;
|
||||
PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor;
|
||||
ULONG GlobalSize, ActualSize;
|
||||
PVOID Buffer;
|
||||
ASSERT("Tag != FREE_POOL_TAG");
|
||||
SAC_DBG(SAC_DBG_MM, "Entering.\n");
|
||||
|
||||
ASSERT("Tag != FREE_POOL_TAG");
|
||||
/* Acquire the memory allocation lock and align the size request */
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);;
|
||||
PoolSize = ALIGN_UP(PoolSize, ULONGLONG);
|
||||
|
||||
SAC_DBG(SAC_DBG_MM, "Entering.\n");
|
||||
|
||||
OldIrql = KfAcquireSpinLock(&MemoryLock);
|
||||
PoolSize = ALIGN_UP(PoolSize, ULONGLONG);
|
||||
|
||||
GlobalDescriptor = GlobalMemoryList;
|
||||
#if _USE_SAC_HEAP_ALLOCATOR_
|
||||
GlobalDescriptor = GlobalMemoryList;
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
while (GlobalDescriptor)
|
||||
{
|
||||
|
@ -189,43 +193,60 @@ MyAllocatePool(
|
|||
LocalDescriptor->Size = PoolSize;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Shut the compiler up */
|
||||
NewDescriptor = GlobalDescriptor = NULL;
|
||||
GlobalSize = (ULONG)NewDescriptor;
|
||||
ActualSize = GlobalSize;
|
||||
NextDescriptor = (PVOID)ActualSize;
|
||||
NewDescriptor = (PVOID)NextDescriptor;
|
||||
|
||||
LocalDescriptor->Tag = Tag;
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
/* Use the NT pool allocator */
|
||||
LocalDescriptor = ExAllocatePoolWithTag(NonPagedPool,
|
||||
PoolSize + sizeof(*LocalDescriptor),
|
||||
Tag);
|
||||
LocalDescriptor->Size = PoolSize;
|
||||
#endif
|
||||
/* Set the tag, and release the lock */
|
||||
LocalDescriptor->Tag = Tag;
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
|
||||
InterlockedIncrement(&TotalAllocations);
|
||||
InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size);
|
||||
SAC_DBG(1, "Returning block 0x%X.\n", LocalDescriptor);
|
||||
/* Update our performance counters */
|
||||
InterlockedIncrement(&TotalAllocations);
|
||||
InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size);
|
||||
|
||||
Buffer = LocalDescriptor + 1;
|
||||
RtlZeroMemory(Buffer, PoolSize);
|
||||
return Buffer;
|
||||
/* Return the buffer and zero it */
|
||||
SAC_DBG(SAC_DBG_MM, "Returning block 0x%X.\n", LocalDescriptor);
|
||||
Buffer = LocalDescriptor + 1;
|
||||
RtlZeroMemory(Buffer, PoolSize);
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
VOID
|
||||
MyFreePool(
|
||||
IN PVOID *Block
|
||||
)
|
||||
NTAPI
|
||||
MyFreePool(IN PVOID *Block)
|
||||
{
|
||||
PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor;
|
||||
PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor;
|
||||
ULONG GlobalSize, LocalSize;
|
||||
PSAC_MEMORY_LIST GlobalDescriptor;
|
||||
KIRQL OldIrql;
|
||||
PSAC_MEMORY_ENTRY NextDescriptor;
|
||||
PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor;
|
||||
PSAC_MEMORY_ENTRY LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY));
|
||||
ULONG GlobalSize, LocalSize;
|
||||
PSAC_MEMORY_LIST GlobalDescriptor;
|
||||
KIRQL OldIrql;
|
||||
SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor);
|
||||
|
||||
LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY));
|
||||
/* Make sure this was a valid entry */
|
||||
ASSERT(LocalDescriptor->Size > 0);
|
||||
ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
|
||||
|
||||
SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor);
|
||||
/* Update performance counters */
|
||||
InterlockedIncrement(&TotalFrees);
|
||||
InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size);
|
||||
|
||||
ASSERT(LocalDescriptor->Size > 0);
|
||||
ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
|
||||
/* Acquire the memory alliocation lock */
|
||||
GlobalDescriptor = GlobalMemoryList;
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
|
||||
InterlockedIncrement(&TotalFrees);
|
||||
|
||||
InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size);
|
||||
|
||||
GlobalDescriptor = GlobalMemoryList;
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
#if _USE_SAC_HEAP_ALLOCATOR_
|
||||
while (GlobalDescriptor)
|
||||
{
|
||||
ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
|
||||
|
@ -297,10 +318,22 @@ MyFreePool(
|
|||
FoundDescriptor->Size +=
|
||||
(LocalDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
|
||||
}
|
||||
#else
|
||||
/* Shut the compiler up */
|
||||
LocalSize = GlobalSize = 0;
|
||||
ThisDescriptor = (PVOID)LocalSize;
|
||||
NextDescriptor = (PVOID)GlobalSize;
|
||||
GlobalDescriptor = (PVOID) ThisDescriptor;
|
||||
FoundDescriptor = (PVOID)GlobalDescriptor;
|
||||
GlobalDescriptor = (PVOID) NextDescriptor;
|
||||
NextDescriptor = (PVOID) FoundDescriptor;
|
||||
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
*Block = NULL;
|
||||
/* Use the NT pool allocator*/
|
||||
ExFreePool(LocalDescriptor);
|
||||
#endif
|
||||
|
||||
SAC_DBG(SAC_DBG_MM, "exiting.\n");
|
||||
return;
|
||||
/* Release the lock, delete the address, and return */
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
*Block = NULL;
|
||||
SAC_DBG(SAC_DBG_MM, "exiting.\n");
|
||||
}
|
||||
|
|
|
@ -1,143 +1,373 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/rawchan.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/rawchan.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
#define SAC_RAW_OBUFFER_SIZE 0x2000
|
||||
#define SAC_RAW_IBUFFER_SIZE 0x2000
|
||||
|
||||
NTSTATUS
|
||||
RawChannelCreate(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
RawChannelCreate(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
CHECK_PARAMETER(Channel);
|
||||
|
||||
Channel->OBuffer = SacAllocatePool(SAC_RAW_OBUFFER_SIZE, GLOBAL_BLOCK_TAG);
|
||||
CHECK_ALLOCATION(Channel->OBuffer);
|
||||
|
||||
Channel->IBuffer = SacAllocatePool(SAC_RAW_IBUFFER_SIZE, GLOBAL_BLOCK_TAG);
|
||||
CHECK_ALLOCATION(Channel->IBuffer);
|
||||
|
||||
Channel->OBufferIndex = 0;
|
||||
Channel->OBufferFirstGoodIndex = 0;
|
||||
Channel->ChannelHasNewIBufferData = FALSE;
|
||||
Channel->ChannelHasNewOBufferData = FALSE;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RawChannelDestroy(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
RawChannelDestroy(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
CHECK_PARAMETER(Channel);
|
||||
|
||||
if (Channel->OBuffer)
|
||||
{
|
||||
SacFreePool(Channel->OBuffer);
|
||||
}
|
||||
|
||||
if (Channel->IBuffer)
|
||||
{
|
||||
SacFreePool(Channel->IBuffer);
|
||||
}
|
||||
|
||||
return ChannelDestroy(Channel);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
ChannelHasNewOBufferData(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return Channel->ChannelHasNewOBufferData;
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
ChannelHasNewIBufferData(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return Channel->ChannelHasNewIBufferData;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RawChannelORead(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
OUT PULONG ByteCount
|
||||
)
|
||||
NTAPI
|
||||
RawChannelORead(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
OUT PULONG ByteCount)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
ULONG NextIndex;
|
||||
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Buffer);
|
||||
CHECK_PARAMETER3(BufferSize > 0);
|
||||
CHECK_PARAMETER4(ByteCount);
|
||||
|
||||
*ByteCount = 0;
|
||||
|
||||
if (ChannelHasNewOBufferData(Channel))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
Buffer[(*ByteCount)++] = Channel->OBuffer[Channel->OBufferFirstGoodIndex];
|
||||
|
||||
NextIndex = (Channel->OBufferFirstGoodIndex + 1) & (SAC_OBUFFER_SIZE - 1);
|
||||
Channel->OBufferFirstGoodIndex = NextIndex;
|
||||
|
||||
if (NextIndex == Channel->OBufferIndex)
|
||||
{
|
||||
_InterlockedExchange(&Channel->ChannelHasNewOBufferData, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT(*ByteCount > 0);
|
||||
|
||||
if (*ByteCount >= BufferSize) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_NO_DATA_DETECTED;
|
||||
}
|
||||
|
||||
if (Channel->OBufferFirstGoodIndex == Channel->OBufferIndex)
|
||||
{
|
||||
ASSERT(ChannelHasNewOBufferData(Channel) == FALSE);
|
||||
}
|
||||
|
||||
if (ChannelHasNewOBufferData(Channel) == FALSE)
|
||||
{
|
||||
ASSERT(Channel->OBufferFirstGoodIndex == Channel->OBufferIndex);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RawChannelOEcho(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR String,
|
||||
IN ULONG Length
|
||||
)
|
||||
NTAPI
|
||||
RawChannelOEcho(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR String,
|
||||
IN ULONG Length)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(String);
|
||||
|
||||
if (Length)
|
||||
{
|
||||
Status = ConMgrWriteData(Channel, String, Length);
|
||||
if (NT_SUCCESS(Status)) ConMgrFlushData(Channel);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RawChannelOWrite2(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR String,
|
||||
IN ULONG Size
|
||||
)
|
||||
NTAPI
|
||||
RawChannelOWrite2(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR String,
|
||||
IN ULONG Size)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
BOOLEAN Overflow;
|
||||
ULONG i, NextIndex;
|
||||
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(String);
|
||||
|
||||
Overflow = FALSE;
|
||||
|
||||
for (i = 0; i < Size; i++)
|
||||
{
|
||||
if ((Channel->OBufferIndex == Channel->OBufferFirstGoodIndex) &&
|
||||
((i) || (ChannelHasNewOBufferData(Channel))))
|
||||
{
|
||||
Overflow = TRUE;
|
||||
}
|
||||
|
||||
ASSERT(Channel->OBufferIndex < SAC_RAW_OBUFFER_SIZE);
|
||||
|
||||
Channel->OBuffer[Channel->OBufferIndex] = String[i];
|
||||
|
||||
NextIndex = (Channel->OBufferIndex + 1) & (SAC_RAW_OBUFFER_SIZE - 1);
|
||||
Channel->OBufferIndex = NextIndex;
|
||||
|
||||
if (Overflow) Channel->OBufferFirstGoodIndex = NextIndex;
|
||||
}
|
||||
|
||||
_InterlockedExchange(&Channel->ChannelHasNewOBufferData, 1);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RawChannelOFlush(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
RawChannelOFlush(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
ULONG ByteCount;
|
||||
CHAR Dummy;
|
||||
CHECK_PARAMETER1(Channel);
|
||||
|
||||
while (ChannelHasNewOBufferData(Channel))
|
||||
{
|
||||
Status = RawChannelORead(Channel, &Dummy, sizeof(Dummy), &ByteCount);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
CHECK_PARAMETER_WITH_STATUS(ByteCount == 1, STATUS_UNSUCCESSFUL);
|
||||
|
||||
Status = ConMgrWriteData(Channel, &Dummy, sizeof(Dummy));
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
|
||||
return ConMgrFlushData(Channel);
|
||||
}
|
||||
|
||||
ULONG
|
||||
RawChannelGetIBufferIndex(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
RawChannelGetIBufferIndex(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return 0;
|
||||
ASSERT(Channel);
|
||||
ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE);
|
||||
|
||||
return Channel->IBufferIndex;
|
||||
}
|
||||
|
||||
VOID
|
||||
RawChannelSetIBufferIndex(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN ULONG BufferIndex
|
||||
)
|
||||
NTAPI
|
||||
RawChannelSetIBufferIndex(IN PSAC_CHANNEL Channel,
|
||||
IN ULONG BufferIndex)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ASSERT(Channel);
|
||||
ASSERT(Channel->IBufferIndex < SAC_RAW_IBUFFER_SIZE);
|
||||
|
||||
Channel->IBufferIndex = BufferIndex;
|
||||
Channel->ChannelHasNewIBufferData = BufferIndex != 0;
|
||||
|
||||
if (!Channel->IBufferIndex)
|
||||
{
|
||||
if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)
|
||||
{
|
||||
ChannelClearEvent(Channel, HasNewDataEvent);
|
||||
UNREFERENCED_PARAMETER(Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RawChannelOWrite(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PWCHAR String,
|
||||
IN ULONG Length
|
||||
)
|
||||
NTAPI
|
||||
RawChannelOWrite(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR String,
|
||||
IN ULONG Length)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(String);
|
||||
|
||||
if ((ConMgrIsWriteEnabled(Channel)) && (Channel->WriteEnabled))
|
||||
{
|
||||
return RawChannelOEcho(Channel, String, Length);
|
||||
}
|
||||
|
||||
return RawChannelOWrite2(Channel, String, Length);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RawChannelIRead(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN PULONG ReturnBufferSize
|
||||
)
|
||||
NTAPI
|
||||
RawChannelIRead(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize,
|
||||
IN PULONG ReturnBufferSize)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
ULONG CopyChars;
|
||||
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Buffer);
|
||||
CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE);
|
||||
|
||||
*ReturnBufferSize = 0;
|
||||
|
||||
if (Channel->ChannelInputBufferLength(Channel) == 0)
|
||||
{
|
||||
ASSERT(ChannelHasNewIBufferData(Channel) == FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyChars = Channel->ChannelInputBufferLength(Channel);
|
||||
if (CopyChars > BufferSize) CopyChars = BufferSize;
|
||||
ASSERT(CopyChars <= Channel->ChannelInputBufferLength(Channel));
|
||||
|
||||
RtlCopyMemory(Buffer, Channel->IBuffer, CopyChars);
|
||||
|
||||
RawChannelSetIBufferIndex(Channel,
|
||||
RawChannelGetIBufferIndex(Channel) - CopyChars);
|
||||
|
||||
if (Channel->ChannelInputBufferLength(Channel))
|
||||
{
|
||||
RtlMoveMemory(Channel->IBuffer,
|
||||
&Channel->IBuffer[CopyChars],
|
||||
Channel->ChannelInputBufferLength(Channel));
|
||||
}
|
||||
|
||||
*ReturnBufferSize = CopyChars;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RawChannelIBufferIsFull(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
PBOOLEAN BufferStatus
|
||||
)
|
||||
NTAPI
|
||||
RawChannelIBufferIsFull(IN PSAC_CHANNEL Channel,
|
||||
OUT PBOOLEAN BufferStatus)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(BufferStatus);
|
||||
|
||||
*BufferStatus = RawChannelGetIBufferIndex(Channel) > SAC_RAW_IBUFFER_SIZE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ULONG
|
||||
RawChannelIBufferLength(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
RawChannelIBufferLength(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return 0;
|
||||
ASSERT(Channel);
|
||||
return RawChannelGetIBufferIndex(Channel);
|
||||
}
|
||||
|
||||
CHAR
|
||||
RawChannelIReadLast(
|
||||
IN PSAC_CHANNEL Channel
|
||||
)
|
||||
NTAPI
|
||||
RawChannelIReadLast(IN PSAC_CHANNEL Channel)
|
||||
{
|
||||
return 0;
|
||||
UCHAR LastChar = 0;
|
||||
|
||||
ASSERT(Channel);
|
||||
|
||||
if (Channel->ChannelInputBufferLength(Channel))
|
||||
{
|
||||
RawChannelSetIBufferIndex(Channel, RawChannelGetIBufferIndex(Channel) - 1);
|
||||
|
||||
LastChar = Channel->IBuffer[RawChannelGetIBufferIndex(Channel)];
|
||||
Channel->IBuffer[RawChannelGetIBufferIndex(Channel)] = 0;
|
||||
}
|
||||
|
||||
return LastChar;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RawChannelIWrite(
|
||||
IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize
|
||||
)
|
||||
NTAPI
|
||||
RawChannelIWrite(IN PSAC_CHANNEL Channel,
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufferSize)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
NTSTATUS Status;
|
||||
BOOLEAN IsFull;
|
||||
ULONG Index;
|
||||
|
||||
CHECK_PARAMETER1(Channel);
|
||||
CHECK_PARAMETER2(Buffer);
|
||||
CHECK_PARAMETER_WITH_STATUS(BufferSize > 0, STATUS_INVALID_BUFFER_SIZE);
|
||||
|
||||
Status = RawChannelIBufferIsFull(Channel, &IsFull);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
if (IsFull) return STATUS_UNSUCCESSFUL;
|
||||
|
||||
Index = RawChannelGetIBufferIndex(Channel);
|
||||
if ((SAC_RAW_IBUFFER_SIZE - Index) >= BufferSize) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
RtlCopyMemory(&Channel->IBuffer[Index], Buffer, BufferSize);
|
||||
|
||||
RawChannelSetIBufferIndex(Channel, BufferSize + Index);
|
||||
|
||||
if (Channel->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)
|
||||
{
|
||||
ChannelSetEvent(Channel, HasNewDataEvent);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/base/sac/driver/sacdrv.rc
|
||||
* PURPOSE: Resource File for EMS SAC Driver
|
||||
|
|
|
@ -1,18 +1,760 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Boot Loader
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/util.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
* PROJECT: ReactOS Drivers
|
||||
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||
* FILE: drivers/sac/driver/util.c
|
||||
* PURPOSE: Driver for the Server Administration Console (SAC) for EMS
|
||||
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "sacdrv.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
PCHAR Utf8ConversionBuffer;
|
||||
ULONG Utf8ConversionBufferSize;
|
||||
PSAC_MACHINE_INFO MachineInformation;
|
||||
PVOID RequestSacCmdEventObjectBody;
|
||||
PKEVENT RequestSacCmdEventWaitObjectBody;
|
||||
PVOID RequestSacCmdSuccessEventObjectBody;
|
||||
PKEVENT RequestSacCmdSuccessEventWaitObjectBody;
|
||||
PVOID RequestSacCmdFailureEventObjectBody;
|
||||
PKEVENT RequestSacCmdFailureEventWaitObjectBody;
|
||||
PFILE_OBJECT ServiceProcessFileObject;
|
||||
BOOLEAN HaveUserModeServiceCmdEventInfo;
|
||||
|
||||
PSAC_MESSAGE_ENTRY GlobalMessageTable;
|
||||
ULONG GlobalMessageTableCount;
|
||||
|
||||
LONG SerialPortConsumerIndex, SerialPortProducerIndex;
|
||||
PCHAR SerialPortBuffer;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
SacTranslateUnicodeToUtf8(IN PWCHAR SourceBuffer,
|
||||
IN ULONG SourceBufferLength,
|
||||
OUT PCHAR DestinationBuffer,
|
||||
IN ULONG DestinationBufferSize,
|
||||
OUT PULONG UTF8Count,
|
||||
OUT PULONG ProcessedCount)
|
||||
{
|
||||
ASSERT(FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
PWCHAR
|
||||
NTAPI
|
||||
GetMessage(IN ULONG MessageIndex)
|
||||
{
|
||||
PSAC_MESSAGE_ENTRY MessageEntry;
|
||||
ULONG i;
|
||||
PWCHAR MessageData = NULL;
|
||||
|
||||
/* Loop all cached messages */
|
||||
for (i = 0; i < GlobalMessageTableCount; i++)
|
||||
{
|
||||
/* Check if this one matches the index */
|
||||
MessageEntry = &GlobalMessageTable[i];
|
||||
if (MessageEntry->Index == MessageIndex)
|
||||
{
|
||||
/* It does, return the buffer */
|
||||
MessageData = MessageEntry->Buffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We should always find it */
|
||||
if (!MessageData) ASSERT(FALSE);
|
||||
return MessageData;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
UTF8EncodeAndSend(IN PWCHAR String)
|
||||
{
|
||||
ULONG ProcessedCount, Utf8Count, i;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
/* Call the translator routine */
|
||||
if (SacTranslateUnicodeToUtf8(String,
|
||||
wcslen(String),
|
||||
Utf8ConversionBuffer,
|
||||
Utf8ConversionBufferSize,
|
||||
&Utf8Count,
|
||||
&ProcessedCount))
|
||||
{
|
||||
/* Loop every character */
|
||||
for (i = 0; i < Utf8Count; i++)
|
||||
{
|
||||
/* Send it to the terminal */
|
||||
Status = HeadlessDispatch(HeadlessCmdPutData,
|
||||
&Utf8ConversionBuffer[i],
|
||||
sizeof(Utf8ConversionBuffer[i]),
|
||||
NULL,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Conversion failed */
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
SacFormatMessage(IN PWCHAR FormattedString,
|
||||
IN PWCHAR MessageString,
|
||||
IN ULONG MessageSize)
|
||||
{
|
||||
/* FIXME: For now don't format anything */
|
||||
wcsncpy(FormattedString, MessageString, MessageSize / sizeof(WCHAR));
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PreloadGlobalMessageTable(IN PVOID ImageBase)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG MessageId, TotalLength, TextSize, i;
|
||||
PWCHAR StringBuffer;
|
||||
PMESSAGE_RESOURCE_ENTRY MessageEntry;
|
||||
PAGED_CODE();
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC PreloadGlobalMessageTable: Entering.\n");
|
||||
|
||||
/* Nothing to do if we already have a table */
|
||||
if (GlobalMessageTable) goto Exit;
|
||||
|
||||
/* Loop through up to 200 messages */
|
||||
TotalLength = 0;
|
||||
for (MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++)
|
||||
{
|
||||
/* Find this message ID in the string table*/
|
||||
Status = RtlFindMessage(ImageBase,
|
||||
11,
|
||||
LANG_NEUTRAL,
|
||||
MessageId,
|
||||
&MessageEntry);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Make sure it's Unicode */
|
||||
ASSERT(MessageEntry->Flags & MESSAGE_RESOURCE_UNICODE);
|
||||
|
||||
/* Remove the space taken up by the OS header, and add our own */
|
||||
TotalLength += MessageEntry->Length -
|
||||
FIELD_OFFSET(MESSAGE_RESOURCE_ENTRY, Text) +
|
||||
sizeof(SAC_MESSAGE_ENTRY);
|
||||
|
||||
/* One more in the table */
|
||||
GlobalMessageTableCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/* We should've found at least one message... */
|
||||
if (!TotalLength)
|
||||
{
|
||||
/* Bail out otherwise */
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC PreloadGlobalMessageTable: No Messages.\n");
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Allocate space for the buffers and headers */
|
||||
GlobalMessageTable = SacAllocatePool(TotalLength, GLOBAL_BLOCK_TAG);
|
||||
if (!GlobalMessageTable)
|
||||
{
|
||||
/* Bail out if we couldn't allocate it */
|
||||
Status = STATUS_NO_MEMORY;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* All the buffers are going to be at the end of the table */
|
||||
StringBuffer = (PWCHAR)(&GlobalMessageTable[GlobalMessageTableCount]);
|
||||
|
||||
/* Now loop over our entries again */
|
||||
for (i = 0, MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++)
|
||||
{
|
||||
/* Make sure the message is still there...! */
|
||||
Status = RtlFindMessage(ImageBase,
|
||||
11,
|
||||
LANG_NEUTRAL,
|
||||
MessageId,
|
||||
&MessageEntry);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Write the entry in the message table*/
|
||||
GlobalMessageTable[i].Index = MessageId;
|
||||
GlobalMessageTable[i].Buffer = StringBuffer;
|
||||
|
||||
/* The structure includes the size of the header, elide it */
|
||||
TextSize = MessageEntry->Length -
|
||||
FIELD_OFFSET(MESSAGE_RESOURCE_ENTRY, Text);
|
||||
|
||||
/* Format the message into the entry. It should be same or smaller */
|
||||
SacFormatMessage(StringBuffer, (PWCHAR)MessageEntry->Text, TextSize);
|
||||
ASSERT((ULONG)(wcslen(StringBuffer)*sizeof(WCHAR)) <= TextSize);
|
||||
|
||||
/* Move to the next buffer space */
|
||||
StringBuffer += TextSize;
|
||||
|
||||
/* Move to the next entry, make sure the status is full success */
|
||||
i++;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
/* All done, return the status code */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Exiting with status 0x%0x\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
TearDownGlobalMessageTable(VOID)
|
||||
{
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Entering.\n");
|
||||
|
||||
/* Free the table if one existed */
|
||||
if (GlobalMessageTable) SacFreePool(GlobalMessageTable);
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC TearDownGlobalMessageTable: Exiting\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
TranslateMachineInformationXML(IN PWCHAR *Buffer,
|
||||
IN PWCHAR ExtraData)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG Size;
|
||||
PWCHAR p;
|
||||
CHECK_PARAMETER1(Buffer);
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
Size = wcslen(L"<machine-info>\r\n");
|
||||
|
||||
if (MachineInformation->MachineName)
|
||||
{
|
||||
Size += wcslen(MachineInformation->MachineName);
|
||||
Size += wcslen(L"<name>%s</name>\r\n");
|
||||
}
|
||||
|
||||
if (MachineInformation->MachineGuid)
|
||||
{
|
||||
Size += wcslen(MachineInformation->MachineGuid);
|
||||
Size += wcslen(L"<guid>%s</guid>\r\n");
|
||||
}
|
||||
|
||||
if (MachineInformation->ProcessorArchitecture)
|
||||
{
|
||||
Size += wcslen(MachineInformation->ProcessorArchitecture);
|
||||
Size += wcslen(L"<processor-architecture>%s</processor-architecture>\r\n");
|
||||
}
|
||||
|
||||
if (MachineInformation->MajorVersion)
|
||||
{
|
||||
Size += wcslen(MachineInformation->MajorVersion);
|
||||
Size += wcslen(L"<os-version>%s</os-version>\r\n");
|
||||
}
|
||||
|
||||
if (MachineInformation->BuildNumber)
|
||||
{
|
||||
Size += wcslen(MachineInformation->BuildNumber);
|
||||
Size += wcslen(L"<os-build-number>%s</os-build-number>\r\n");
|
||||
}
|
||||
|
||||
if (MachineInformation->ProductType)
|
||||
{
|
||||
Size += wcslen(MachineInformation->ProductType);
|
||||
Size += wcslen(L"<os-product>%s</os-product>\r\n");
|
||||
}
|
||||
|
||||
if (MachineInformation->ServicePack)
|
||||
{
|
||||
Size += wcslen(MachineInformation->ServicePack);
|
||||
Size += wcslen(L"<os-service-pack>%s</os-service-pack>\r\n");
|
||||
}
|
||||
|
||||
if (ExtraData) Size += wcslen(ExtraData);
|
||||
|
||||
Size += wcslen(L"</machine-info>\r\n");
|
||||
|
||||
p = (PWCHAR)SacAllocatePool((Size + sizeof(ANSI_NULL)) * sizeof(WCHAR), GLOBAL_BLOCK_TAG);
|
||||
|
||||
*Buffer = p;
|
||||
if (!p) return STATUS_NO_MEMORY;
|
||||
|
||||
Size = wcslen(L"<machine-info>\r\n");
|
||||
wcscpy(p, L"<machine-info>\r\n");
|
||||
|
||||
p += Size;
|
||||
|
||||
if (MachineInformation->MachineName)
|
||||
{
|
||||
p += swprintf(p, L"<name>%s</name>\r\n", MachineInformation->MachineName);
|
||||
}
|
||||
|
||||
if (MachineInformation->MachineGuid)
|
||||
{
|
||||
p += swprintf(p, L"<guid>%s</guid>\r\n", MachineInformation->MachineGuid);
|
||||
}
|
||||
|
||||
if (MachineInformation->ProcessorArchitecture)
|
||||
{
|
||||
p += swprintf(p, L"<processor-architecture>%s</processor-architecture>\r\n", MachineInformation->ProcessorArchitecture);
|
||||
}
|
||||
|
||||
if (MachineInformation->MajorVersion)
|
||||
{
|
||||
p += swprintf(p, L"<os-version>%s</os-version>\r\n", MachineInformation->MajorVersion);
|
||||
}
|
||||
|
||||
if (MachineInformation->BuildNumber)
|
||||
{
|
||||
p += swprintf(p, L"<os-build-number>%s</os-build-number>\r\n", MachineInformation->BuildNumber);
|
||||
}
|
||||
|
||||
if (MachineInformation->ProductType)
|
||||
{
|
||||
p += swprintf(p, L"<os-product>%s</os-product>\r\n", MachineInformation->ProductType);
|
||||
}
|
||||
|
||||
if (MachineInformation->ServicePack)
|
||||
{
|
||||
p += swprintf(p, L"<os-service-pack>%s</os-service-pack>\r\n", MachineInformation->ServicePack);
|
||||
}
|
||||
|
||||
if (ExtraData)
|
||||
{
|
||||
Size = wcslen(ExtraData);
|
||||
wcscpy(p, ExtraData);
|
||||
p += Size;
|
||||
}
|
||||
|
||||
wcscpy(p, L"</machine-info>\r\n");
|
||||
ASSERT((((ULONG) wcslen(*Buffer) + 1) * sizeof(WCHAR)) <= Size);
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
InitializeMachineInformation(VOID)
|
||||
{
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Entering.\n");
|
||||
|
||||
/* FIXME: TODO */
|
||||
MachineInformation = NULL;
|
||||
ASSERT(FALSE);
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Exiting with error.\n");
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
GetRegistryValueBuffer(IN PCWSTR KeyName,
|
||||
IN PWCHAR ValueName,
|
||||
IN PKEY_VALUE_PARTIAL_INFORMATION* Buffer)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING DestinationString;
|
||||
HANDLE Handle;
|
||||
SIZE_T ResultLength = 0;
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: Entering.\n");
|
||||
CHECK_PARAMETER1(KeyName);
|
||||
CHECK_PARAMETER2(ValueName);
|
||||
|
||||
/* Open the specified key */
|
||||
RtlInitUnicodeString(&DestinationString, KeyName);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DestinationString,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenKey(&Handle,
|
||||
KEY_WRITE | SYNCHRONIZE | KEY_READ,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Bail out on failure */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: failed ZwOpenKey: %X.\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Query the size of the key */
|
||||
RtlInitUnicodeString(&DestinationString, ValueName);
|
||||
Status = ZwQueryValueKey(Handle,
|
||||
&DestinationString,
|
||||
KeyValuePartialInformation,
|
||||
NULL,
|
||||
0,
|
||||
&ResultLength);
|
||||
if (!ResultLength) return Status;
|
||||
|
||||
/* Allocate the buffer for the partial info structure and our integer data */
|
||||
ResultLength += sizeof(ULONG);
|
||||
*Buffer = SacAllocatePool(ResultLength, GLOBAL_BLOCK_TAG);
|
||||
if (!*Buffer)
|
||||
{
|
||||
SAC_DBG(1, "SAC GetRegistryValueBuffer: failed allocation\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Now read the data */
|
||||
Status = ZwQueryValueKey(Handle,
|
||||
&DestinationString,
|
||||
KeyValuePartialInformation,
|
||||
*Buffer,
|
||||
ResultLength,
|
||||
&ResultLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Free the buffer if we couldn't read the data */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC GetRegistryValueBuffer: failed ZwQueryValueKey: %X.\n", Status);
|
||||
SacFreePool(*Buffer);
|
||||
}
|
||||
|
||||
/* Return the result */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Exiting.\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SetRegistryValue(IN PCWSTR KeyName,
|
||||
IN PWCHAR ValueName,
|
||||
IN ULONG Type,
|
||||
IN PVOID Data,
|
||||
IN ULONG DataSize)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING DestinationString;
|
||||
HANDLE Handle;
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Entering.\n");
|
||||
CHECK_PARAMETER1(KeyName);
|
||||
CHECK_PARAMETER2(ValueName);
|
||||
CHECK_PARAMETER4(Data);
|
||||
|
||||
/* Open the specified key */
|
||||
RtlInitUnicodeString(&DestinationString, KeyName);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DestinationString,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenKey(&Handle,
|
||||
KEY_WRITE | SYNCHRONIZE | KEY_READ,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Bail out on failure */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: failed ZwOpenKey: %X.\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Set the specified value */
|
||||
RtlInitUnicodeString(&DestinationString, ValueName);
|
||||
Status = ZwSetValueKey(Handle, &DestinationString, 0, Type, Data, DataSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Print error on failure */
|
||||
SAC_DBG(1, "SAC SetRegistryValue: failed ZwSetValueKey: %X.\n", Status);
|
||||
}
|
||||
|
||||
/* Close the handle and exit */
|
||||
NtClose(Handle);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC SetRegistryValue: Exiting.\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CopyRegistryValueData(IN PULONG* Buffer,
|
||||
IN PKEY_VALUE_PARTIAL_INFORMATION PartialInfo)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
CHECK_PARAMETER1(Buffer);
|
||||
CHECK_PARAMETER2(PartialInfo);
|
||||
|
||||
/* Allocate space for registry data */
|
||||
*Buffer = SacAllocatePool(PartialInfo->DataLength, GLOBAL_BLOCK_TAG);
|
||||
if (*Buffer)
|
||||
{
|
||||
/* Copy the data into the buffer */
|
||||
RtlCopyMemory(*Buffer, PartialInfo->Data, PartialInfo->DataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the correct error code */
|
||||
SAC_DBG(SAC_DBG_UTIL, "SAC CopyRegistryValueBuffer: Failed ALLOCATE.\n");
|
||||
Status = STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Return the result */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
GetCommandConsoleLaunchingPermission(OUT PBOOLEAN Permission)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PKEY_VALUE_PARTIAL_INFORMATION Dummy;
|
||||
|
||||
/* Assume success and read the key */
|
||||
*Permission = TRUE;
|
||||
Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacdrv",
|
||||
L"DisableCmdSessions",
|
||||
&Dummy);
|
||||
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
{
|
||||
/* The default is success */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Only if the key is present and set, do we disable permission */
|
||||
if (NT_SUCCESS(Status)) *Permission = FALSE;
|
||||
}
|
||||
|
||||
/* Return status */
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ImposeSacCmdServiceStartTypePolicy(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PKEY_VALUE_PARTIAL_INFORMATION Buffer = NULL;
|
||||
PULONG Data;
|
||||
|
||||
/* Read the service start type*/
|
||||
Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacsvr",
|
||||
L"Start",
|
||||
&Buffer);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* If there's no start type, fail, as this is unusual */
|
||||
if (!Buffer) return STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* Read the value */
|
||||
Status = CopyRegistryValueData(&Data, Buffer);
|
||||
SacFreePool(Buffer);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Check what the current start type is */
|
||||
switch (*Data)
|
||||
{
|
||||
/* It's boot, system, or disabled */
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
/* Leave it as is */
|
||||
return Status;
|
||||
|
||||
case 3:
|
||||
|
||||
/* It's set to automatic, set it to system instead */
|
||||
*Data = 2;
|
||||
Status = SetRegistryValue(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\sacsvr",
|
||||
L"Start",
|
||||
REG_DWORD,
|
||||
Data,
|
||||
sizeof(ULONG));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC ImposeSacCmdServiceStartTypePolicy: Failed SetRegistryValue: %X\n", Status);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
InitializeCmdEventInfo(VOID)
|
||||
{
|
||||
/* Check if we were already initailized */
|
||||
if (HaveUserModeServiceCmdEventInfo)
|
||||
{
|
||||
/* Full state expected */
|
||||
ASSERT(RequestSacCmdEventObjectBody);
|
||||
ASSERT(RequestSacCmdSuccessEventObjectBody);
|
||||
ASSERT(RequestSacCmdFailureEventObjectBody);
|
||||
|
||||
/* Dereference each wait object in turn */
|
||||
if (RequestSacCmdEventObjectBody)
|
||||
{
|
||||
ObDereferenceObject(RequestSacCmdEventObjectBody);
|
||||
}
|
||||
|
||||
if (RequestSacCmdSuccessEventObjectBody)
|
||||
{
|
||||
ObDereferenceObject(RequestSacCmdSuccessEventObjectBody);
|
||||
}
|
||||
|
||||
if (RequestSacCmdFailureEventObjectBody)
|
||||
{
|
||||
ObDereferenceObject(RequestSacCmdFailureEventObjectBody);
|
||||
}
|
||||
}
|
||||
|
||||
/* Claer everything */
|
||||
RequestSacCmdEventObjectBody = NULL;
|
||||
RequestSacCmdEventWaitObjectBody = NULL;
|
||||
RequestSacCmdSuccessEventObjectBody = NULL;
|
||||
RequestSacCmdSuccessEventWaitObjectBody = NULL;
|
||||
RequestSacCmdFailureEventObjectBody = NULL;
|
||||
RequestSacCmdFailureEventWaitObjectBody = NULL;
|
||||
ServiceProcessFileObject = NULL;
|
||||
|
||||
/* Reset state */
|
||||
HaveUserModeServiceCmdEventInfo = FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RegisterBlueScreenMachineInformation(VOID)
|
||||
{
|
||||
PWCHAR XmlBuffer;
|
||||
PHEADLESS_BLUE_SCREEN_DATA BsBuffer;
|
||||
ULONG Length, HeaderLength, TotalLength;
|
||||
NTSTATUS Status;
|
||||
ULONG i;
|
||||
|
||||
/* Create the XML buffer and make sure it's OK */
|
||||
Status = TranslateMachineInformationXML(&XmlBuffer, NULL);
|
||||
CHECK_PARAMETER_WITH_STATUS(NT_SUCCESS(Status), Status);
|
||||
CHECK_PARAMETER_WITH_STATUS(XmlBuffer, STATUS_UNSUCCESSFUL);
|
||||
|
||||
/* Compute the sizes and allocate a buffer for it */
|
||||
Length = wcslen(XmlBuffer);
|
||||
HeaderLength = strlen("MACHINEINFO");
|
||||
TotalLength = HeaderLength +
|
||||
Length +
|
||||
sizeof(*BsBuffer) +
|
||||
2 * sizeof(ANSI_NULL);
|
||||
BsBuffer = SacAllocatePool(TotalLength, GLOBAL_BLOCK_TAG);
|
||||
CHECK_PARAMETER_WITH_STATUS(BsBuffer, STATUS_NO_MEMORY);
|
||||
|
||||
/* Copy the XML property name */
|
||||
strcpy((PCHAR)BsBuffer->XMLData, "MACHINEINFO");
|
||||
BsBuffer->Property = (PUCHAR)HeaderLength + sizeof(ANSI_NULL);
|
||||
|
||||
/* Copy the data and NULL-terminate it */
|
||||
for (i = 0; i < Length; i++)
|
||||
{
|
||||
BsBuffer->XMLData[HeaderLength + sizeof(ANSI_NULL) + i] = XmlBuffer[i];
|
||||
}
|
||||
BsBuffer->XMLData[HeaderLength + sizeof(ANSI_NULL) + i] = ANSI_NULL;
|
||||
|
||||
/* Let the OS save the buffer for later */
|
||||
Status = HeadlessDispatch(HeadlessCmdSetBlueScreenData,
|
||||
BsBuffer,
|
||||
TotalLength,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Failure or not, we don't need this anymore */
|
||||
SacFreePool(BsBuffer);
|
||||
SacFreePool(XmlBuffer);
|
||||
|
||||
/* Return the result */
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information: Exiting.\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
FreeMachineInformation(VOID)
|
||||
{
|
||||
ASSERT(MachineInformation);
|
||||
|
||||
/* Free every cached string of machine information */
|
||||
if (MachineInformation->MachineName) SacFreePool(MachineInformation);
|
||||
if (MachineInformation->MachineGuid) SacFreePool(MachineInformation->MachineGuid);
|
||||
if (MachineInformation->ProcessorArchitecture) SacFreePool(MachineInformation->ProcessorArchitecture);
|
||||
if (MachineInformation->MajorVersion) SacFreePool(MachineInformation->MajorVersion);
|
||||
if (MachineInformation->BuildNumber) SacFreePool(MachineInformation->BuildNumber);
|
||||
if (MachineInformation->ProductType) SacFreePool(MachineInformation->ProductType);
|
||||
if (MachineInformation->ServicePack) SacFreePool(MachineInformation->ServicePack);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VerifyEventWaitable(IN HANDLE Handle,
|
||||
OUT PVOID *WaitObject,
|
||||
OUT PVOID *ActualWaitObject)
|
||||
{
|
||||
PVOID Object;
|
||||
NTSTATUS Status;
|
||||
POBJECT_TYPE ObjectType;
|
||||
|
||||
/* Reference the object */
|
||||
Status = ObReferenceObjectByHandle(Handle,
|
||||
EVENT_ALL_ACCESS,
|
||||
NULL,
|
||||
KernelMode,
|
||||
&Object,
|
||||
NULL);
|
||||
*WaitObject = Object;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC VerifyEventWaitable: Unable to reference event object (%lx)\n", Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check if the object itself is NOT being used */
|
||||
ObjectType = OBJECT_TO_OBJECT_HEADER(Object)->Type;
|
||||
if (ObjectType->TypeInfo.UseDefaultObject == FALSE)
|
||||
{
|
||||
/* Get the actual object that's being used for the wait */
|
||||
*ActualWaitObject = (PVOID)((ULONG_PTR)Object +
|
||||
(ULONG_PTR)ObjectType->DefaultObject);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Drop the reference we took */
|
||||
SAC_DBG(SAC_DBG_INIT, "SAC VerifyEventWaitable: event object not waitable!\n");
|
||||
ObDereferenceObject(*WaitObject);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SerialBufferGetChar(OUT PCHAR Char)
|
||||
{
|
||||
/* Check if nothing's been produced yet */
|
||||
if (SerialPortConsumerIndex == SerialPortProducerIndex)
|
||||
{
|
||||
return STATUS_NO_DATA_DETECTED;
|
||||
}
|
||||
|
||||
/* Consume the produced character and clear it*/
|
||||
*Char = SerialPortBuffer[SerialPortConsumerIndex];
|
||||
SerialPortBuffer[SerialPortConsumerIndex] = ANSI_NULL;
|
||||
|
||||
/* Advance the index and return success */
|
||||
_InterlockedExchange(&SerialPortConsumerIndex,
|
||||
(SerialPortConsumerIndex + 1) &
|
||||
(SAC_SERIAL_PORT_BUFFER_SIZE - 1));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ULONG
|
||||
ConvertAnsiToUnicode(
|
||||
|
@ -32,24 +774,6 @@ IsCmdEventRegistrationProcess(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
InitializeCmdEventInfo(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
VerifyEventWaitable(
|
||||
IN PVOID Object,
|
||||
OUT PVOID *WaitObject,
|
||||
OUT PVOID *ActualWaitObject
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
InvokeUserModeService(
|
||||
VOID
|
||||
|
@ -58,32 +782,6 @@ InvokeUserModeService(
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
SacFormatMessage(
|
||||
IN PWCHAR FormattedString,
|
||||
IN PWCHAR MessageString,
|
||||
IN ULONG MessageSize
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
TearDownGlobalMessageTable(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
PWCHAR
|
||||
GetMessage(
|
||||
IN ULONG MessageIndex
|
||||
)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SacTranslateUtf8ToUnicode(
|
||||
IN CHAR Utf8Char,
|
||||
|
@ -94,50 +792,6 @@ SacTranslateUtf8ToUnicode(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
SacTranslateUnicodeToUtf8(
|
||||
IN PWCHAR SourceBuffer,
|
||||
IN ULONG SourceBufferLength,
|
||||
OUT PCHAR DestinationBuffer,
|
||||
IN ULONG DestinationBufferSize,
|
||||
IN ULONG UTF8Count,
|
||||
OUT PULONG ProcessedCount
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
GetRegistryValueBuffer(
|
||||
IN PCWSTR KeyName,
|
||||
IN PWCHAR ValueName,
|
||||
IN PKEY_VALUE_PARTIAL_INFORMATION ValueBuffer
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
SetRegistryValue(
|
||||
IN PCWSTR KeyName,
|
||||
IN PWCHAR ValueName,
|
||||
IN ULONG Type,
|
||||
IN PVOID Data,
|
||||
IN ULONG DataSize
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CopyRegistryValueData(
|
||||
IN PVOID Dest,
|
||||
IN PKEY_VALUE_PARTIAL_INFORMATION ValueBuffer
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
TranslateMachineInformationText(
|
||||
IN PWCHAR Buffer)
|
||||
|
@ -145,55 +799,6 @@ TranslateMachineInformationText(
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
TranslateMachineInformationXML(
|
||||
IN PWCHAR Buffer,
|
||||
IN PWCHAR ExtraData
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
RegisterBlueScreenMachineInformation(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
FreeMachineInformation(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
SerialBufferGetChar(
|
||||
OUT PCHAR Char
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
GetCommandConsoleLaunchingPermission(
|
||||
OUT PBOOLEAN Permission
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ImposeSacCmdServiceStartTypePolicy(
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
CopyAndInsertStringAtInterval(
|
||||
IN PWCHAR SourceStr,
|
||||
|
@ -229,11 +834,3 @@ UnregisterSacCmdEvent(
|
|||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
UTF8EncodeAndSend(
|
||||
IN PWCHAR String
|
||||
)
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* This file is part of the w64 mingw-runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*/
|
||||
|
||||
#ifndef _TIME_H__S
|
||||
#define _TIME_H__S
|
||||
|
||||
|
@ -14,22 +15,110 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
_CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _strdate_s(char *_Buf,size_t _SizeInBytes);
|
||||
_CRTIMP errno_t __cdecl _strtime_s(char *_Buf ,size_t _SizeInBytes);
|
||||
_CRTIMP errno_t __cdecl _ctime64_s(char *_Buf,size_t _SizeInBytes,const __time64_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _gmtime64_s(struct tm *_Tm,const __time64_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _localtime64_s(struct tm *_Tm,const __time64_t *_Time);
|
||||
_Success_(return == 0)
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_ctime32_s(
|
||||
_Out_writes_(_SizeInBytes) _Post_readable_size_(26) char *_Buf,
|
||||
_In_ size_t _SizeInBytes,
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_gmtime32_s(
|
||||
_In_ struct tm *_Tm,
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_localtime32_s(
|
||||
_Out_ struct tm *_Tm,
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_strdate_s(
|
||||
_Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf,
|
||||
_In_range_(>= , 9) size_t _SizeInBytes);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_strtime_s(
|
||||
_Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf,
|
||||
_In_range_(>= , 9) size_t _SizeInBytes);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_ctime64_s(
|
||||
_Out_writes_z_(_SizeInBytes) char *_Buf,
|
||||
_In_ size_t _SizeInBytes,
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_gmtime64_s(
|
||||
_Out_ struct tm *_Tm,
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_localtime64_s(
|
||||
_Out_ struct tm *_Tm,
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
#ifndef _WTIME_S_DEFINED
|
||||
#define _WTIME_S_DEFINED
|
||||
_CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm);
|
||||
_CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords);
|
||||
_CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords);
|
||||
_CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wasctime_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf,
|
||||
_In_range_(>= , 26) size_t _SizeInWords,
|
||||
_In_ const struct tm *_Tm);
|
||||
|
||||
_Success_(return == 0)
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wctime32_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wstrdate_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wstrtime_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf,
|
||||
_In_range_(>= , 9) size_t _SizeInWords);
|
||||
|
||||
_Success_(return == 0)
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wctime64_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
#if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL)
|
||||
#define _INC_WTIME_S_INL
|
||||
|
@ -38,7 +127,8 @@ extern "C" {
|
|||
__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); }
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _WTIME_S_DEFINED */
|
||||
|
||||
#ifndef RC_INVOKED
|
||||
#ifdef _USE_32BIT_TIME_T
|
||||
|
@ -52,5 +142,6 @@ __CRT_INLINE errno_t __cdecl localtime_s(struct tm *_Tm,const time_t *_Time) { r
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif /* MINGW_HAS_SECURE_API */
|
||||
|
||||
#endif /* _TIME_H__S */
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* This file is part of the w64 mingw-runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*/
|
||||
|
||||
#ifndef _INC_WCHAR_S
|
||||
#define _INC_WCHAR_S
|
||||
|
||||
|
@ -16,100 +17,648 @@ extern "C" {
|
|||
|
||||
#ifndef _WIO_S_DEFINED
|
||||
#define _WIO_S_DEFINED
|
||||
_CRTIMP errno_t __cdecl _waccess_s(const wchar_t *_Filename,int _AccessMode);
|
||||
_CRTIMP errno_t __cdecl _wmktemp_s(wchar_t *_TemplateName,size_t _SizeInWords);
|
||||
#endif
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_waccess_s(
|
||||
_In_z_ const wchar_t *_Filename,
|
||||
_In_ int _AccessMode);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wmktemp_s(
|
||||
_Inout_updates_z_(_SizeInWords) wchar_t *_TemplateName,
|
||||
_In_ size_t _SizeInWords);
|
||||
|
||||
#endif /* _WIO_S_DEFINED */
|
||||
|
||||
#ifndef _WCONIO_S_DEFINED
|
||||
#define _WCONIO_S_DEFINED
|
||||
_CRTIMP errno_t __cdecl _cgetws_s(wchar_t *_Buffer,size_t _SizeInWords,size_t *_SizeRead);
|
||||
_CRTIMP int __cdecl _cwprintf_s(const wchar_t *_Format,...);
|
||||
_CRTIMP int __cdecl _cwscanf_s(const wchar_t *_Format,...);
|
||||
_CRTIMP int __cdecl _cwscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP int __cdecl _vcwprintf_s(const wchar_t *_Format,va_list _ArgList);
|
||||
_CRTIMP int __cdecl _cwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP int __cdecl _vcwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
|
||||
#endif
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_cgetws_s(
|
||||
_Out_writes_to_(_SizeInWords, *_SizeRead) wchar_t *_Buffer,
|
||||
_In_ size_t _SizeInWords,
|
||||
_Out_ size_t *_SizeRead);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_cwprintf_s(
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_cwscanf_s(
|
||||
_In_z_ _Scanf_s_format_string_ const wchar_t *_Format,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_cwscanf_s_l(
|
||||
_In_z_ _Scanf_s_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_vcwprintf_s(
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
va_list _ArgList);
|
||||
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_cwprintf_s_l(
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_vcwprintf_s_l(
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
va_list _ArgList);
|
||||
|
||||
#endif /* _WCONIO_S_DEFINED */
|
||||
|
||||
#ifndef _WSTDIO_S_DEFINED
|
||||
#define _WSTDIO_S_DEFINED
|
||||
_CRTIMP wchar_t *__cdecl _getws_s(wchar_t *_Str,size_t _SizeInWords);
|
||||
int __cdecl fwprintf_s(FILE *_File,const wchar_t *_Format,...);
|
||||
int __cdecl wprintf_s(const wchar_t *_Format,...);
|
||||
int __cdecl vfwprintf_s(FILE *_File,const wchar_t *_Format,va_list _ArgList);
|
||||
int __cdecl vwprintf_s(const wchar_t *_Format,va_list _ArgList);
|
||||
int __cdecl swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...);
|
||||
int __cdecl vswprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,va_list _ArgList);
|
||||
_CRTIMP int __cdecl _snwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,...);
|
||||
_CRTIMP int __cdecl _vsnwprintf_s(wchar_t *_DstBuf,size_t _DstSizeInWords,size_t _MaxCount,const wchar_t *_Format,va_list _ArgList);
|
||||
_CRTIMP int __cdecl _wprintf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP int __cdecl _vwprintf_s_l(const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
|
||||
_CRTIMP int __cdecl _fwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP int __cdecl _vfwprintf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
|
||||
_CRTIMP int __cdecl _swprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP int __cdecl _vswprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
|
||||
_CRTIMP int __cdecl _snwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP int __cdecl _vsnwprintf_s_l(wchar_t *_DstBuf,size_t _DstSize,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,va_list _ArgList);
|
||||
_CRTIMP int __cdecl _fwscanf_s_l(FILE *_File,const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP int __cdecl _swscanf_s_l(const wchar_t *_Src,const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP int __cdecl _snwscanf_s(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,...);
|
||||
_CRTIMP int __cdecl _snwscanf_s_l(const wchar_t *_Src,size_t _MaxCount,const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP int __cdecl _wscanf_s_l(const wchar_t *_Format,_locale_t _Locale,...);
|
||||
_CRTIMP errno_t __cdecl _wfopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode);
|
||||
_CRTIMP errno_t __cdecl _wfreopen_s(FILE **_File,const wchar_t *_Filename,const wchar_t *_Mode,FILE *_OldFile);
|
||||
_CRTIMP errno_t __cdecl _wtmpnam_s(wchar_t *_DstBuf,size_t _SizeInWords);
|
||||
#endif
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
wchar_t *
|
||||
__cdecl
|
||||
_getws_s(
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_Str,
|
||||
_In_ size_t _SizeInWords);
|
||||
|
||||
_Check_return_opt_
|
||||
int
|
||||
__cdecl
|
||||
fwprintf_s(
|
||||
_Inout_ FILE *_File,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
int
|
||||
__cdecl
|
||||
wprintf_s(
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
int
|
||||
__cdecl
|
||||
vfwprintf_s(
|
||||
_Inout_ FILE *_File,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
va_list _ArgList);
|
||||
|
||||
_Check_return_opt_
|
||||
int
|
||||
__cdecl
|
||||
vwprintf_s(
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
va_list _ArgList);
|
||||
|
||||
int
|
||||
__cdecl
|
||||
swprintf_s(
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_Dst,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
...);
|
||||
|
||||
int
|
||||
__cdecl
|
||||
vswprintf_s(
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_Dst,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
va_list _ArgList);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_snwprintf_s(
|
||||
_Out_writes_z_(_DstSizeInWords) wchar_t *_DstBuf,
|
||||
_In_ size_t _DstSizeInWords,
|
||||
_In_ size_t _MaxCount,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_vsnwprintf_s(
|
||||
_Out_writes_z_(_DstSizeInWords) wchar_t *_DstBuf,
|
||||
_In_ size_t _DstSizeInWords,
|
||||
_In_ size_t _MaxCount,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
va_list _ArgList);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_wprintf_s_l(
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_vwprintf_s_l(
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
va_list _ArgList);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_fwprintf_s_l(
|
||||
_Inout_ FILE *_File,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_vfwprintf_s_l(
|
||||
_Inout_ FILE *_File,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
va_list _ArgList);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_swprintf_s_l(
|
||||
_Out_writes_z_(_DstSize) wchar_t *_DstBuf,
|
||||
_In_ size_t _DstSize,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_vswprintf_s_l(
|
||||
_Out_writes_z_(_DstSize) wchar_t *_DstBuf,
|
||||
_In_ size_t _DstSize,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
va_list _ArgList);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_snwprintf_s_l(
|
||||
_Out_writes_z_(_DstSize) wchar_t *_DstBuf,
|
||||
_In_ size_t _DstSize,
|
||||
_In_ size_t _MaxCount,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_vsnwprintf_s_l(
|
||||
_Out_writes_z_(_DstSize) wchar_t *_DstBuf,
|
||||
_In_ size_t _DstSize,
|
||||
_In_ size_t _MaxCount,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
va_list _ArgList);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_fwscanf_s_l(
|
||||
_Inout_ FILE *_File,
|
||||
_In_z_ _Scanf_s_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_swscanf_s_l(
|
||||
_In_z_ const wchar_t *_Src,
|
||||
_In_z_ _Scanf_s_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_snwscanf_s(
|
||||
_In_reads_(_MaxCount) _Pre_z_ const wchar_t *_Src,
|
||||
_In_ size_t _MaxCount,
|
||||
_In_z_ _Scanf_s_format_string_ const wchar_t *_Format,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_snwscanf_s_l(
|
||||
_In_reads_(_MaxCount) _Pre_z_ const wchar_t *_Src,
|
||||
_In_ size_t _MaxCount,
|
||||
_In_z_ _Scanf_s_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_Check_return_opt_
|
||||
_CRTIMP
|
||||
int
|
||||
__cdecl
|
||||
_wscanf_s_l(
|
||||
_In_z_ _Scanf_s_format_string_ const wchar_t *_Format,
|
||||
_In_opt_ _locale_t _Locale,
|
||||
...);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wfopen_s(
|
||||
_Outptr_result_maybenull_ FILE **_File,
|
||||
_In_z_ const wchar_t *_Filename,
|
||||
_In_z_ const wchar_t *_Mode);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wfreopen_s(
|
||||
_Outptr_result_maybenull_ FILE **_File,
|
||||
_In_z_ const wchar_t *_Filename,
|
||||
_In_z_ const wchar_t *_Mode,
|
||||
_Inout_ FILE *_OldFile);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wtmpnam_s(
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_DstBuf,
|
||||
_In_ size_t _SizeInWords);
|
||||
|
||||
#endif /* _WSTDIO_S_DEFINED */
|
||||
|
||||
#ifndef _WSTDLIB_S_DEFINED
|
||||
#define _WSTDLIB_S_DEFINED
|
||||
_CRTIMP errno_t __cdecl _itow_s (int _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
|
||||
_CRTIMP errno_t __cdecl _ltow_s (long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
|
||||
_CRTIMP errno_t __cdecl _ultow_s (unsigned long _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
|
||||
_CRTIMP errno_t __cdecl _wgetenv_s(size_t *_ReturnSize,wchar_t *_DstBuf,size_t _DstSizeInWords,const wchar_t *_VarName);
|
||||
_CRTIMP errno_t __cdecl _wdupenv_s(wchar_t **_Buffer,size_t *_BufferSizeInWords,const wchar_t *_VarName);
|
||||
_CRTIMP errno_t __cdecl _i64tow_s(__int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
|
||||
_CRTIMP errno_t __cdecl _ui64tow_s(unsigned __int64 _Val,wchar_t *_DstBuf,size_t _SizeInWords,int _Radix);
|
||||
#endif
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_itow_s(
|
||||
_In_ int _Val,
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_DstBuf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ int _Radix);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_ltow_s(
|
||||
_In_ long _Val,
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_DstBuf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ int _Radix);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_ultow_s(
|
||||
_In_ unsigned long _Val,
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_DstBuf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ int _Radix);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wgetenv_s(
|
||||
_Out_ size_t *_ReturnSize,
|
||||
_Out_writes_z_(_DstSizeInWords) wchar_t *_DstBuf,
|
||||
_In_ size_t _DstSizeInWords,
|
||||
_In_z_ const wchar_t *_VarName);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wdupenv_s(
|
||||
_Outptr_result_buffer_maybenull_(*_BufferSizeInWords) _Deref_post_z_ wchar_t **_Buffer,
|
||||
_Out_opt_ size_t *_BufferSizeInWords,
|
||||
_In_z_ const wchar_t *_VarName);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_i64tow_s(
|
||||
_In_ __int64 _Val,
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_DstBuf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ int _Radix);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_ui64tow_s(
|
||||
_In_ unsigned __int64 _Val,
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_DstBuf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ int _Radix);
|
||||
|
||||
#endif /* _WSTDLIB_S_DEFINED */
|
||||
|
||||
#ifndef _POSIX_
|
||||
#ifndef _WSTDLIBP_S_DEFINED
|
||||
#define _WSTDLIBP_S_DEFINED
|
||||
_CRTIMP errno_t __cdecl _wmakepath_s(wchar_t *_PathResult,size_t _SizeInWords,const wchar_t *_Drive,const wchar_t *_Dir,const wchar_t *_Filename,const wchar_t *_Ext);
|
||||
_CRTIMP errno_t __cdecl _wputenv_s(const wchar_t *_Name,const wchar_t *_Value);
|
||||
_CRTIMP errno_t __cdecl _wsearchenv_s(const wchar_t *_Filename,const wchar_t *_EnvVar,wchar_t *_ResultPath,size_t _SizeInWords);
|
||||
_CRTIMP errno_t __cdecl _wsplitpath_s(const wchar_t *_FullPath,wchar_t *_Drive,size_t _DriveSizeInWords,wchar_t *_Dir,size_t _DirSizeInWords,wchar_t *_Filename,size_t _FilenameSizeInWords,wchar_t *_Ext,size_t _ExtSizeInWords);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wmakepath_s(
|
||||
_Out_writes_z_(_SizeInBytes) wchar_t *_PathResult,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_opt_z_ const wchar_t *_Drive,
|
||||
_In_opt_z_ const wchar_t *_Dir,
|
||||
_In_opt_z_ const wchar_t *_Filename,
|
||||
_In_opt_z_ const wchar_t *_Ext);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wputenv_s(
|
||||
_In_z_ const wchar_t *_Name,
|
||||
_In_z_ const wchar_t *_Value);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wsearchenv_s(
|
||||
_In_z_ const wchar_t *_Filename,
|
||||
_In_z_ const wchar_t *_EnvVar,
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_ResultPath,
|
||||
_In_ size_t _SizeInWords);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wsplitpath_s(
|
||||
_In_z_ const wchar_t *_FullPath,
|
||||
_Out_writes_opt_z_(_DriveSizeInWords) wchar_t *_Drive,
|
||||
_In_ size_t _DriveSizeInWords,
|
||||
_Out_writes_opt_z_(_DirSizeInWords) wchar_t *_Dir,
|
||||
_In_ size_t _DirSizeInWords,
|
||||
_Out_writes_opt_z_(_FilenameSizeInWords) wchar_t *_Filename,
|
||||
_In_ size_t _FilenameSizeInWords,
|
||||
_Out_writes_opt_z_(_ExtSizeInWords) wchar_t *_Ext,
|
||||
_In_ size_t _ExtSizeInWords);
|
||||
|
||||
#endif /* _WSTDLIBP_S_DEFINED */
|
||||
#endif /* _POSIX_ */
|
||||
|
||||
#ifndef _WSTRING_S_DEFINED
|
||||
#define _WSTRING_S_DEFINED
|
||||
_CRTIMP wchar_t *__cdecl wcstok_s(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context);
|
||||
_CRTIMP errno_t __cdecl _wcserror_s(wchar_t *_Buf,size_t _SizeInWords,int _ErrNum);
|
||||
_CRTIMP errno_t __cdecl __wcserror_s(wchar_t *_Buffer,size_t _SizeInWords,const wchar_t *_ErrMsg);
|
||||
_CRTIMP errno_t __cdecl _wcsnset_s(wchar_t *_Dst,size_t _DstSizeInWords,wchar_t _Val,size_t _MaxCount);
|
||||
_CRTIMP errno_t __cdecl _wcsset_s(wchar_t *_Str,size_t _SizeInWords,wchar_t _Val);
|
||||
_CRTIMP errno_t __cdecl _wcslwr_s(wchar_t *_Str,size_t _SizeInWords);
|
||||
_CRTIMP errno_t __cdecl _wcslwr_s_l(wchar_t *_Str,size_t _SizeInWords,_locale_t _Locale);
|
||||
_CRTIMP errno_t __cdecl _wcsupr_s(wchar_t *_Str,size_t _Size);
|
||||
_CRTIMP errno_t __cdecl _wcsupr_s_l(wchar_t *_Str,size_t _Size,_locale_t _Locale);
|
||||
|
||||
_CRTIMP errno_t __cdecl wcsncat_s(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount);
|
||||
_CRTIMP errno_t __cdecl _wcsncat_s_l(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale);
|
||||
_CRTIMP errno_t __cdecl wcsncpy_s(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount);
|
||||
_CRTIMP errno_t __cdecl _wcsncpy_s_l(wchar_t *_Dst,size_t _DstSizeInChars,const wchar_t *_Src,size_t _MaxCount,_locale_t _Locale);
|
||||
_CRTIMP wchar_t *__cdecl _wcstok_s_l(wchar_t *_Str,const wchar_t *_Delim,wchar_t **_Context,_locale_t _Locale);
|
||||
_CRTIMP errno_t __cdecl _wcsset_s_l(wchar_t *_Str,size_t _SizeInChars,unsigned int _Val,_locale_t _Locale);
|
||||
_CRTIMP errno_t __cdecl _wcsnset_s_l(wchar_t *_Str,size_t _SizeInChars,unsigned int _Val, size_t _Count,_locale_t _Locale);
|
||||
_Check_return_
|
||||
_CRTIMP
|
||||
wchar_t *
|
||||
__cdecl
|
||||
wcstok_s(
|
||||
_Inout_opt_z_ wchar_t *_Str,
|
||||
_In_z_ const wchar_t *_Delim,
|
||||
_Inout_ _Deref_prepost_opt_z_ wchar_t **_Context);
|
||||
|
||||
#endif
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcserror_s(
|
||||
_Out_writes_opt_z_(_SizeInWords) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ int _ErrNum);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
__wcserror_s(
|
||||
_Out_writes_opt_z_(_SizeInWords) wchar_t *_Buffer,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_z_ const wchar_t *_ErrMsg);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcsnset_s(
|
||||
_Inout_updates_z_(_DstSizeInWords) wchar_t *_Dst,
|
||||
_In_ size_t _DstSizeInWords,
|
||||
wchar_t _Val,
|
||||
_In_ size_t _MaxCount);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcsset_s(
|
||||
_Inout_updates_z_(_SizeInWords) wchar_t *_Str,
|
||||
_In_ size_t _SizeInWords,
|
||||
wchar_t _Val);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcslwr_s(
|
||||
_Inout_updates_z_(_SizeInWords) wchar_t *_Str,
|
||||
_In_ size_t _SizeInWords);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcslwr_s_l(
|
||||
_Inout_updates_z_(_SizeInWords) wchar_t *_Str,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_opt_ _locale_t _Locale);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcsupr_s(
|
||||
_Inout_updates_z_(_Size) wchar_t *_Str,
|
||||
_In_ size_t _Size);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcsupr_s_l(
|
||||
_Inout_updates_z_(_Size) wchar_t *_Str,
|
||||
_In_ size_t _Size,
|
||||
_In_opt_ _locale_t _Locale);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
wcsncat_s(
|
||||
_Inout_updates_z_(_DstSizeInChars) wchar_t *_Dst,
|
||||
_In_ size_t _DstSizeInChars,
|
||||
_In_z_ const wchar_t *_Src,
|
||||
_In_ size_t _MaxCount);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcsncat_s_l(
|
||||
_Inout_updates_z_(_DstSizeInChars) wchar_t *_Dst,
|
||||
_In_ size_t _DstSizeInChars,
|
||||
_In_z_ const wchar_t *_Src,
|
||||
_In_ size_t _MaxCount,
|
||||
_In_opt_ _locale_t _Locale);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
wcsncpy_s(
|
||||
_Out_writes_z_(_DstSizeInChars) wchar_t *_Dst,
|
||||
_In_ size_t _DstSizeInChars,
|
||||
_In_z_ const wchar_t *_Src,
|
||||
_In_ size_t _MaxCount);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcsncpy_s_l(
|
||||
_Out_writes_z_(_DstSizeInChars) wchar_t *_Dst,
|
||||
_In_ size_t _DstSizeInChars,
|
||||
_In_z_ const wchar_t *_Src,
|
||||
_In_ size_t _MaxCount,
|
||||
_In_opt_ _locale_t _Locale);
|
||||
|
||||
_CRTIMP
|
||||
wchar_t *
|
||||
__cdecl
|
||||
_wcstok_s_l(
|
||||
wchar_t *_Str,
|
||||
const wchar_t *_Delim,
|
||||
wchar_t **_Context,
|
||||
_locale_t _Locale);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcsset_s_l(
|
||||
wchar_t *_Str,
|
||||
size_t _SizeInChars,
|
||||
unsigned int _Val,
|
||||
_locale_t _Locale);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wcsnset_s_l(
|
||||
wchar_t *_Str,
|
||||
size_t _SizeInChars,
|
||||
unsigned int _Val,
|
||||
size_t _Count,
|
||||
_locale_t _Locale);
|
||||
|
||||
#endif /* _WSTRING_S_DEFINED */
|
||||
|
||||
#ifndef _WTIME_S_DEFINED
|
||||
#define _WTIME_S_DEFINED
|
||||
_CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm);
|
||||
_CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords);
|
||||
_CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords);
|
||||
_CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wasctime_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ const struct tm *_Tm);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wctime32_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wstrdate_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf,
|
||||
_In_range_(>= , 9) size_t _SizeInWords);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wstrtime_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wctime64_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
#if !defined (RC_INVOKED) && !defined (_INC_WTIME_S_INL)
|
||||
#define _INC_WTIME_S_INL
|
||||
|
@ -117,16 +666,46 @@ extern "C" {
|
|||
#ifndef _USE_32BIT_TIME_T
|
||||
__CRT_INLINE errno_t __cdecl _wctime_s(wchar_t *_Buffer,size_t _SizeInWords,const time_t *_Time) { return _wctime64_s(_Buffer,_SizeInWords,_Time); }
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_CRTIMP errno_t __cdecl mbsrtowcs_s(size_t *_Retval,wchar_t *_Dst,size_t _SizeInWords,const char **_PSrc,size_t _N,mbstate_t *_State);
|
||||
_CRTIMP errno_t __cdecl wcrtomb_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,wchar_t _Ch,mbstate_t *_State);
|
||||
_CRTIMP errno_t __cdecl wcsrtombs_s(size_t *_Retval,char *_Dst,size_t _SizeInBytes,const wchar_t **_Src,size_t _Size,mbstate_t *_State);
|
||||
#endif /* _WTIME_S_DEFINED */
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
mbsrtowcs_s(
|
||||
_Out_opt_ size_t *_Retval,
|
||||
_Out_writes_opt_z_(_SizeInWords) wchar_t *_Dst,
|
||||
_In_ size_t _SizeInWords,
|
||||
_Inout_ _Deref_prepost_opt_valid_ const char **_PSrc,
|
||||
_In_ size_t _N,
|
||||
_Out_opt_ mbstate_t *_State);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
wcrtomb_s(
|
||||
_Out_opt_ size_t *_Retval,
|
||||
_Out_writes_opt_z_(_SizeInBytes) char *_Dst,
|
||||
_In_ size_t _SizeInBytes,
|
||||
_In_ wchar_t _Ch,
|
||||
_Out_opt_ mbstate_t *_State);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
wcsrtombs_s(
|
||||
_Out_opt_ size_t *_Retval,
|
||||
_Out_writes_bytes_to_opt_(_SizeInBytes, *_Retval) char *_Dst,
|
||||
_In_ size_t _SizeInBytes,
|
||||
_Inout_ _Deref_prepost_z_ const wchar_t **_Src,
|
||||
_In_ size_t _Size,
|
||||
_Out_opt_ mbstate_t *_State);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif /* MINGW_HAS_SECURE_API */
|
||||
|
||||
#endif /* _INC_WCHAR_S */
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* This file is part of the w64 mingw-runtime package.
|
||||
* No warranty is given; refer to the file DISCLAIMER within this package.
|
||||
*/
|
||||
|
||||
#ifndef _TIME_H_
|
||||
#define _TIME_H_
|
||||
|
||||
|
@ -92,67 +93,295 @@ extern "C" {
|
|||
_CRTDATA(extern long _timezone);
|
||||
_CRTDATA(extern char * _tzname[2]);
|
||||
|
||||
_CRTIMP errno_t __cdecl _get_daylight(int *_Daylight);
|
||||
_CRTIMP errno_t __cdecl _get_dstbias(long *_Daylight_savings_bias);
|
||||
_CRTIMP errno_t __cdecl _get_timezone(long *_Timezone);
|
||||
_CRTIMP errno_t __cdecl _get_tzname(size_t *_ReturnValue,char *_Buffer,size_t _SizeInBytes,int _Index);
|
||||
_CRTIMP errno_t __cdecl _get_daylight(_Out_ int *_Daylight);
|
||||
_CRTIMP errno_t __cdecl _get_dstbias(_Out_ long *_Daylight_savings_bias);
|
||||
_CRTIMP errno_t __cdecl _get_timezone(_Out_ long *_Timezone);
|
||||
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(asctime_s) char *__cdecl asctime(const struct tm *_Tm);
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(_ctime32_s) char *__cdecl _ctime32(const __time32_t *_Time);
|
||||
_CRTIMP clock_t __cdecl clock(void);
|
||||
_CRTIMP double __cdecl _difftime32(__time32_t _Time1,__time32_t _Time2);
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(_gmtime32_s) struct tm *__cdecl _gmtime32(const __time32_t *_Time);
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(_localtime32_s) struct tm *__cdecl _localtime32(const __time32_t *_Time);
|
||||
_CRTIMP size_t __cdecl strftime(char *_Buf,size_t _SizeInBytes,const char *_Format,const struct tm *_Tm);
|
||||
_CRTIMP size_t __cdecl _strftime_l(char *_Buf,size_t _Max_size,const char *_Format,const struct tm *_Tm,_locale_t _Locale);
|
||||
_CRTIMP char *__cdecl _strdate(char *_Buffer);
|
||||
_CRTIMP char *__cdecl _strtime(char *_Buffer);
|
||||
_CRTIMP __time32_t __cdecl _time32(__time32_t *_Time);
|
||||
_CRTIMP __time32_t __cdecl _mktime32(struct tm *_Tm);
|
||||
_CRTIMP __time32_t __cdecl _mkgmtime32(struct tm *_Tm);
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_get_tzname(
|
||||
_Out_ size_t *_ReturnValue,
|
||||
_Out_writes_z_(_SizeInBytes) char *_Buffer,
|
||||
_In_ size_t _SizeInBytes,
|
||||
_In_ int _Index);
|
||||
|
||||
_Check_return_
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(asctime_s)
|
||||
char *
|
||||
__cdecl
|
||||
asctime(
|
||||
_In_ const struct tm *_Tm);
|
||||
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(_ctime32_s)
|
||||
char *
|
||||
__cdecl
|
||||
_ctime32(
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_Check_return_ _CRTIMP clock_t __cdecl clock(void);
|
||||
|
||||
_CRTIMP
|
||||
double
|
||||
__cdecl
|
||||
_difftime32(
|
||||
_In_ __time32_t _Time1,
|
||||
_In_ __time32_t _Time2);
|
||||
|
||||
_Check_return_
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(_gmtime32_s)
|
||||
struct tm *
|
||||
__cdecl
|
||||
_gmtime32(
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(_localtime32_s)
|
||||
struct tm *
|
||||
__cdecl
|
||||
_localtime32(
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_Success_(return > 0)
|
||||
_CRTIMP
|
||||
size_t
|
||||
__cdecl
|
||||
strftime(
|
||||
_Out_writes_z_(_SizeInBytes) char *_Buf,
|
||||
_In_ size_t _SizeInBytes,
|
||||
_In_z_ _Printf_format_string_ const char *_Format,
|
||||
_In_ const struct tm *_Tm);
|
||||
|
||||
_Success_(return > 0)
|
||||
_CRTIMP
|
||||
size_t
|
||||
__cdecl
|
||||
_strftime_l(
|
||||
_Out_writes_z_(_Max_size) char *_Buf,
|
||||
_In_ size_t _Max_size,
|
||||
_In_z_ _Printf_format_string_ const char *_Format,
|
||||
_In_ const struct tm *_Tm,
|
||||
_In_opt_ _locale_t _Locale);
|
||||
|
||||
_CRTIMP char *__cdecl _strdate(_Out_writes_z_(9) char *_Buffer);
|
||||
_CRTIMP char *__cdecl _strtime(_Out_writes_z_(9) char *_Buffer);
|
||||
_CRTIMP __time32_t __cdecl _time32(_Out_opt_ __time32_t *_Time);
|
||||
_CRTIMP __time32_t __cdecl _mktime32(_Inout_ struct tm *_Tm);
|
||||
_CRTIMP __time32_t __cdecl _mkgmtime32(_Inout_ struct tm *_Tm);
|
||||
_CRTIMP void __cdecl _tzset(void);
|
||||
_CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _getsystime(struct tm *_Tm);
|
||||
_CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _setsystime(struct tm *_Tm,unsigned _MilliSec);
|
||||
_CRT_OBSOLETE(GetLocalTime) unsigned __cdecl _getsystime(_Out_ struct tm *_Tm);
|
||||
|
||||
_CRTIMP errno_t __cdecl asctime_s(char *_Buf,size_t _SizeInWords,const struct tm *_Tm);
|
||||
_CRTIMP errno_t __cdecl _ctime32_s(char *_Buf,size_t _SizeInBytes,const __time32_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _gmtime32_s(struct tm *_Tm,const __time32_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _localtime32_s(struct tm *_Tm,const __time32_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _strdate_s(char *_Buf,size_t _SizeInBytes);
|
||||
_CRTIMP errno_t __cdecl _strtime_s(char *_Buf ,size_t _SizeInBytes);
|
||||
_CRT_OBSOLETE(GetLocalTime)
|
||||
unsigned
|
||||
__cdecl
|
||||
_setsystime(
|
||||
_In_ struct tm *_Tm,
|
||||
unsigned _MilliSec);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
asctime_s(
|
||||
_Out_writes_(_SizeInBytes) _Post_readable_size_(26) char *_Buf,
|
||||
_In_range_(>= , 26) size_t _SizeInBytes,
|
||||
_In_ const struct tm *_Tm);
|
||||
|
||||
_Success_(return == 0)
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_ctime32_s(
|
||||
_Out_writes_(_SizeInBytes) _Post_readable_size_(26) char *_Buf,
|
||||
_In_ size_t _SizeInBytes,
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_gmtime32_s(
|
||||
_In_ struct tm *_Tm,
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_localtime32_s(
|
||||
_Out_ struct tm *_Tm,
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_strdate_s(
|
||||
_Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf,
|
||||
_In_range_(>= , 9) size_t _SizeInBytes);
|
||||
|
||||
_Check_return_wat_
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_strtime_s(
|
||||
_Out_writes_(_SizeInBytes) _Post_readable_size_(9) char *_Buf,
|
||||
_In_range_(>= , 9) size_t _SizeInBytes);
|
||||
|
||||
#if _INTEGRAL_MAX_BITS >= 64
|
||||
_CRTIMP double __cdecl _difftime64(__time64_t _Time1,__time64_t _Time2);
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(_ctime64_s) char *__cdecl _ctime64(const __time64_t *_Time);
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(_gmtime64_s) struct tm *__cdecl _gmtime64(const __time64_t *_Time);
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(_localtime64_s) struct tm *__cdecl _localtime64(const __time64_t *_Time);
|
||||
_CRTIMP __time64_t __cdecl _mktime64(struct tm *_Tm);
|
||||
_CRTIMP __time64_t __cdecl _mkgmtime64(struct tm *_Tm);
|
||||
_CRTIMP __time64_t __cdecl _time64(__time64_t *_Time);
|
||||
|
||||
_CRTIMP errno_t __cdecl _ctime64_s(char *_Buf,size_t _SizeInBytes,const __time64_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _gmtime64_s(struct tm *_Tm,const __time64_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _localtime64_s(struct tm *_Tm,const __time64_t *_Time);
|
||||
#endif
|
||||
_Check_return_
|
||||
_CRTIMP
|
||||
double
|
||||
__cdecl
|
||||
_difftime64(
|
||||
_In_ __time64_t _Time1,
|
||||
_In_ __time64_t _Time2);
|
||||
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(_ctime64_s)
|
||||
char *
|
||||
__cdecl
|
||||
_ctime64(
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(_gmtime64_s)
|
||||
struct tm *
|
||||
__cdecl
|
||||
_gmtime64(
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(_localtime64_s)
|
||||
struct tm *
|
||||
__cdecl
|
||||
_localtime64(
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
_CRTIMP __time64_t __cdecl _mktime64(_Inout_ struct tm *_Tm);
|
||||
_CRTIMP __time64_t __cdecl _mkgmtime64(_Inout_ struct tm *_Tm);
|
||||
_CRTIMP __time64_t __cdecl _time64(_Out_opt_ __time64_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_ctime64_s(
|
||||
_Out_writes_z_(_SizeInBytes) char *_Buf,
|
||||
_In_ size_t _SizeInBytes,
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_gmtime64_s(
|
||||
_Out_ struct tm *_Tm,
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_localtime64_s(
|
||||
_Out_ struct tm *_Tm,
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
#endif /* _INTEGRAL_MAX_BITS >= 64 */
|
||||
|
||||
#ifndef _WTIME_DEFINED
|
||||
#define _WTIME_DEFINED
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(_wasctime_s) wchar_t *__cdecl _wasctime(const struct tm *_Tm);
|
||||
_CRTIMP wchar_t *__cdecl _wctime(const time_t *_Time);
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(_wctime32_s) wchar_t *__cdecl _wctime32(const __time32_t *_Time);
|
||||
_CRTIMP size_t __cdecl wcsftime(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm);
|
||||
_CRTIMP size_t __cdecl _wcsftime_l(wchar_t *_Buf,size_t _SizeInWords,const wchar_t *_Format,const struct tm *_Tm,_locale_t _Locale);
|
||||
_CRTIMP wchar_t *__cdecl _wstrdate(wchar_t *_Buffer);
|
||||
_CRTIMP wchar_t *__cdecl _wstrtime(wchar_t *_Buffer);
|
||||
|
||||
_CRTIMP errno_t __cdecl _wasctime_s(wchar_t *_Buf,size_t _SizeInWords,const struct tm *_Tm);
|
||||
_CRTIMP errno_t __cdecl _wctime32_s(wchar_t *_Buf,size_t _SizeInWords,const __time32_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _wstrdate_s(wchar_t *_Buf,size_t _SizeInWords);
|
||||
_CRTIMP errno_t __cdecl _wstrtime_s(wchar_t *_Buf,size_t _SizeInWords);
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(_wasctime_s)
|
||||
wchar_t *
|
||||
__cdecl
|
||||
_wasctime(
|
||||
_In_ const struct tm *_Tm);
|
||||
|
||||
_CRTIMP wchar_t *__cdecl _wctime(const time_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(_wctime32_s)
|
||||
wchar_t *
|
||||
__cdecl
|
||||
_wctime32(
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_Success_(return > 0)
|
||||
_CRTIMP
|
||||
size_t
|
||||
__cdecl
|
||||
wcsftime(
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_ const struct tm *_Tm);
|
||||
|
||||
_Success_(return > 0)
|
||||
_CRTIMP
|
||||
size_t
|
||||
__cdecl
|
||||
_wcsftime_l(
|
||||
_Out_writes_z_(_SizeInWords) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_z_ _Printf_format_string_ const wchar_t *_Format,
|
||||
_In_ const struct tm *_Tm,
|
||||
_In_opt_ _locale_t _Locale);
|
||||
|
||||
_CRTIMP wchar_t *__cdecl _wstrdate(_Out_writes_z_(9) wchar_t *_Buffer);
|
||||
_CRTIMP wchar_t *__cdecl _wstrtime(_Out_writes_z_(9) wchar_t *_Buffer);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wasctime_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf,
|
||||
_In_range_(>= , 26) size_t _SizeInWords,
|
||||
_In_ const struct tm *_Tm);
|
||||
|
||||
_Success_(return == 0)
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wctime32_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ const __time32_t *_Time);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wstrdate_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords);
|
||||
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wstrtime_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(9) wchar_t *_Buf,
|
||||
_In_range_(>= , 9) size_t _SizeInWords);
|
||||
|
||||
#if _INTEGRAL_MAX_BITS >= 64
|
||||
_CRTIMP _CRT_INSECURE_DEPRECATE(_wctime64_s) wchar_t *__cdecl _wctime64(const __time64_t *_Time);
|
||||
_CRTIMP errno_t __cdecl _wctime64_s(wchar_t *_Buf,size_t _SizeInWords,const __time64_t *_Time);
|
||||
#endif
|
||||
|
||||
_CRTIMP
|
||||
_CRT_INSECURE_DEPRECATE(_wctime64_s)
|
||||
wchar_t *
|
||||
__cdecl
|
||||
_wctime64(
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
_Success_(return == 0)
|
||||
_CRTIMP
|
||||
errno_t
|
||||
__cdecl
|
||||
_wctime64_s(
|
||||
_Out_writes_(_SizeInWords) _Post_readable_size_(26) wchar_t *_Buf,
|
||||
_In_ size_t _SizeInWords,
|
||||
_In_ const __time64_t *_Time);
|
||||
|
||||
#endif /* _INTEGRAL_MAX_BITS >= 64 */
|
||||
|
||||
#if !defined (RC_INVOKED) && !defined (_INC_WTIME_INL)
|
||||
#define _INC_WTIME_INL
|
||||
|
@ -218,4 +447,3 @@ __CRT_INLINE time_t __cdecl time(time_t *_Time) { return _time64(_Time); }
|
|||
#pragma pack(pop)
|
||||
|
||||
#endif /* End _TIME_H_ */
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ extern POBJECT_TYPE NTSYSAPI IoDriverObjectType;
|
|||
#define DNF_LEGACY_DRIVER 0x00004000
|
||||
#define DNF_STOPPED 0x00008000
|
||||
#define DNF_WILL_BE_REMOVED 0x00010000
|
||||
#define DNF_NEED_TO_ENUM 0x00020000
|
||||
#define DNF_LEGACY_RESOURCE_DEVICENODE 0x00020000
|
||||
#define DNF_NOT_CONFIGURED 0x00040000
|
||||
#define DNF_REINSTALL 0x00080000
|
||||
#define DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED 0x00100000 // ???
|
||||
|
|
|
@ -89,11 +89,17 @@ extern POBJECT_TYPE NTSYSAPI PsJobType;
|
|||
//
|
||||
// Flags for NtCreateProcessEx
|
||||
//
|
||||
#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001
|
||||
#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002
|
||||
#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004
|
||||
#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001
|
||||
#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002
|
||||
#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004
|
||||
#define PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00000008
|
||||
#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010
|
||||
#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010
|
||||
#define PROCESS_CREATE_FLAGS_ALL_LARGE_PAGE_FLAGS PROCESS_CREATE_FLAGS_LARGE_PAGES
|
||||
#define PROCESS_CREATE_FLAGS_LEGAL_MASK (PROCESS_CREATE_FLAGS_BREAKAWAY | \
|
||||
PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT | \
|
||||
PROCESS_CREATE_FLAGS_INHERIT_HANDLES | \
|
||||
PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE | \
|
||||
PROCESS_CREATE_FLAGS_ALL_LARGE_PAGE_FLAGS)
|
||||
|
||||
//
|
||||
// Process priority classes
|
||||
|
@ -106,18 +112,6 @@ extern POBJECT_TYPE NTSYSAPI PsJobType;
|
|||
#define PROCESS_PRIORITY_CLASS_BELOW_NORMAL 5
|
||||
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL 6
|
||||
|
||||
//
|
||||
// NtCreateProcessEx flags
|
||||
//
|
||||
#define PS_REQUEST_BREAKAWAY 1
|
||||
#define PS_NO_DEBUG_INHERIT 2
|
||||
#define PS_INHERIT_HANDLES 4
|
||||
#define PS_LARGE_PAGES 8
|
||||
#define PS_ALL_FLAGS (PS_REQUEST_BREAKAWAY | \
|
||||
PS_NO_DEBUG_INHERIT | \
|
||||
PS_INHERIT_HANDLES | \
|
||||
PS_LARGE_PAGES)
|
||||
|
||||
//
|
||||
// Process base priorities
|
||||
//
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -7,7 +7,8 @@ list(APPEND UNICODE_SOURCE
|
|||
neteventmsg.mc
|
||||
ntiologc.mc
|
||||
ntstatus.mc
|
||||
pciclass.mc)
|
||||
pciclass.mc
|
||||
sacmsg.mc)
|
||||
|
||||
add_message_headers(ANSI ${ANSI_SOURCE})
|
||||
# FIXME: this needs testing before switching to unicode
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
MessageId=1
|
||||
SymbolicName=SACDRV_1
|
||||
SymbolicName=SAC_INIT_STATUS
|
||||
Language=English
|
||||
Computer is booting, SAC started and initialized.\n\nUse the \"ch -?\" command for information about using channels.\nUse the \"?\" command for general help.
|
||||
.
|
||||
|
||||
MessageId=2
|
||||
SymbolicName=SACDRV_2
|
||||
SymbolicName=SAC_NEWLINE
|
||||
Language=English
|
||||
|
||||
.
|
||||
|
||||
MessageId=3
|
||||
SymbolicName=SACDRV_3
|
||||
SymbolicName=SAC_PROMPT
|
||||
Language=English
|
||||
SAC>%0
|
||||
.
|
||||
|
@ -59,9 +59,9 @@ Paging is now OFF.
|
|||
.
|
||||
|
||||
MessageId=11
|
||||
SymbolicName=SACDRV_11
|
||||
SymbolicName=SAC_OUT_OF_MEMORY_PROMPT
|
||||
Language=English
|
||||
Paging is now OFF.
|
||||
THIS LOOKS LIKE A BUG???
|
||||
.
|
||||
|
||||
MessageId=12
|
||||
|
@ -173,7 +173,7 @@ lock Lock access to Command Prompt channels.
|
|||
.
|
||||
|
||||
MessageId=48
|
||||
SymbolicName=SACDRV_48
|
||||
SymbolicName=SAC_FAIL_PROMPT
|
||||
Language=English
|
||||
Failed with status 0x%%X.
|
||||
.
|
||||
|
@ -269,13 +269,13 @@ SAC cannot raise the process priority any higher.
|
|||
.
|
||||
|
||||
MessageId=65
|
||||
SymbolicName=SACDRV_65
|
||||
SymbolicName=SAC_SHUTDOWN_FAIL_PROMPT
|
||||
Language=English
|
||||
SAC failed to shutdown the system.
|
||||
.
|
||||
|
||||
MessageId=66
|
||||
SymbolicName=SACDRV_66
|
||||
SymbolicName=SAC_RESTART_FAIL_PROMPT
|
||||
Language=English
|
||||
SAC failed to restart the system.
|
||||
.
|
||||
|
@ -551,19 +551,19 @@ ch Channel management commands. Use ch -? for more help.
|
|||
.
|
||||
|
||||
MessageId=113
|
||||
SymbolicName=SACDRV_113
|
||||
SymbolicName=SAC_RESTART_TIME_PROMPT
|
||||
Language=English
|
||||
Time since last reboot: %%d:%%02d:%%02d
|
||||
.
|
||||
|
||||
MessageId=114
|
||||
SymbolicName=SACDRV_114
|
||||
SymbolicName=SAC_RESTART_PROMPT
|
||||
Language=English
|
||||
SAC preparing to restart the system.
|
||||
.
|
||||
|
||||
MessageId=115
|
||||
SymbolicName=SACDRV_115
|
||||
SymbolicName=SAC_SHUTDOWN_PROMPT
|
||||
Language=English
|
||||
SAC preparing to shutdown the system.
|
||||
.
|
||||
|
@ -641,13 +641,13 @@ Error: There is no channel present at the specified index.
|
|||
.
|
||||
|
||||
MessageId=144
|
||||
SymbolicName=SACDRV_144
|
||||
SymbolicName=SAC_CHANNEL_NAME
|
||||
Language=English
|
||||
SAC%0
|
||||
.
|
||||
|
||||
MessageId=145
|
||||
SymbolicName=SACDRV_145
|
||||
SymbolicName=SAC_CHANNEL_DESCRIPTION
|
||||
Language=English
|
||||
Special Administration Console%0
|
||||
.
|
||||
|
|
|
@ -908,37 +908,86 @@ IoReportResourceUsage(PUNICODE_STRING DriverClassName,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @halfplemented
|
||||
*/
|
||||
NTSTATUS NTAPI
|
||||
IoAssignResources(PUNICODE_STRING RegistryPath,
|
||||
PUNICODE_STRING DriverClassName,
|
||||
PDRIVER_OBJECT DriverObject,
|
||||
PDEVICE_OBJECT DeviceObject,
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
|
||||
PCM_RESOURCE_LIST* AllocatedResources)
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IopLegacyResourceAllocation(IN ARBITER_REQUEST_SOURCE AllocationType,
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT DeviceObject OPTIONAL,
|
||||
IN PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements,
|
||||
IN OUT PCM_RESOURCE_LIST *AllocatedResources)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1("IoAssignResources is halfplemented!\n");
|
||||
|
||||
*AllocatedResources = NULL;
|
||||
Status = IopFixupResourceListWithRequirements(RequestedResources,
|
||||
DPRINT1("IopLegacyResourceAllocation is halfplemented!\n");
|
||||
|
||||
Status = IopFixupResourceListWithRequirements(ResourceRequirements,
|
||||
AllocatedResources);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_CONFLICTING_ADDRESSES)
|
||||
{
|
||||
DPRINT1("Denying an attempt to claim resources currently in use by another device!\n");
|
||||
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Claim resources in registry */
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IoAssignResources(IN PUNICODE_STRING RegistryPath,
|
||||
IN PUNICODE_STRING DriverClassName,
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
|
||||
IN OUT PCM_RESOURCE_LIST* AllocatedResources)
|
||||
{
|
||||
PDEVICE_NODE DeviceNode;
|
||||
|
||||
/* Do we have a DO? */
|
||||
if (DeviceObject)
|
||||
{
|
||||
/* Get its device node */
|
||||
DeviceNode = IopGetDeviceNode(DeviceObject);
|
||||
if ((DeviceNode) && !(DeviceNode->Flags & DNF_LEGACY_RESOURCE_DEVICENODE))
|
||||
{
|
||||
/* New drivers should not call this API */
|
||||
KeBugCheckEx(PNP_DETECTED_FATAL_ERROR,
|
||||
0,
|
||||
0,
|
||||
(ULONG_PTR)DeviceObject,
|
||||
(ULONG_PTR)DriverObject);
|
||||
}
|
||||
}
|
||||
|
||||
/* Did the driver supply resources? */
|
||||
if (RequestedResources)
|
||||
{
|
||||
/* Make sure there's actually something useful in them */
|
||||
if (!(RequestedResources->AlternativeLists) || !(RequestedResources->List[0].Count))
|
||||
{
|
||||
/* Empty resources are no resources */
|
||||
RequestedResources = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize output if given */
|
||||
if (AllocatedResources) *AllocatedResources = NULL;
|
||||
|
||||
/* Call internal helper function */
|
||||
return IopLegacyResourceAllocation(ArbiterRequestLegacyAssigned,
|
||||
DriverObject,
|
||||
DeviceObject,
|
||||
RequestedResources,
|
||||
AllocatedResources);
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION:
|
||||
* Reads and returns Hardware information from the appropriate hardware registry key.
|
||||
|
|
|
@ -2268,8 +2268,6 @@ IopEnumerateDevice(
|
|||
&DeviceNode->InstancePath);
|
||||
}
|
||||
|
||||
DeviceNode->Flags &= ~DNF_NEED_TO_ENUM;
|
||||
|
||||
DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n");
|
||||
|
||||
Stack.Parameters.QueryDeviceRelations.Type = BusRelations;
|
||||
|
|
|
@ -369,7 +369,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
"ProcessHandle: %p Parent: %p\n", ProcessHandle, ParentProcess);
|
||||
|
||||
/* Validate flags */
|
||||
if (Flags & ~PS_ALL_FLAGS) return STATUS_INVALID_PARAMETER;
|
||||
if (Flags & ~PROCESS_CREATE_FLAGS_LEGAL_MASK) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
/* Check for parent */
|
||||
if (ParentProcess)
|
||||
|
@ -508,7 +508,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
Process->DebugPort = DebugObject;
|
||||
|
||||
/* Check if the caller doesn't want the debug stuff inherited */
|
||||
if (Flags & PS_NO_DEBUG_INHERIT)
|
||||
if (Flags & PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT)
|
||||
{
|
||||
/* Set the process flag */
|
||||
InterlockedOr((PLONG)&Process->Flags, PSF_NO_DEBUG_INHERIT_BIT);
|
||||
|
@ -595,7 +595,8 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
}
|
||||
|
||||
/* Initialize object manager for the process */
|
||||
Status = ObInitProcess(Flags & PS_INHERIT_HANDLES ? Parent : NULL,
|
||||
Status = ObInitProcess(Flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES ?
|
||||
Parent : NULL,
|
||||
Process);
|
||||
if (!NT_SUCCESS(Status)) goto CleanupWithRef;
|
||||
}
|
||||
|
@ -643,7 +644,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
else
|
||||
{
|
||||
/* This is the initial system process */
|
||||
Flags &= ~PS_LARGE_PAGES;
|
||||
Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES;
|
||||
Status = MmInitializeProcessAddressSpace(Process,
|
||||
NULL,
|
||||
NULL,
|
||||
|
@ -1347,9 +1348,9 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
|
|||
"Parent: %p Attributes: %p\n", ParentProcess, ObjectAttributes);
|
||||
|
||||
/* Set new-style flags */
|
||||
if ((ULONG)SectionHandle & 1) Flags = PS_REQUEST_BREAKAWAY;
|
||||
if ((ULONG)DebugPort & 1) Flags |= PS_NO_DEBUG_INHERIT;
|
||||
if (InheritObjectTable) Flags |= PS_INHERIT_HANDLES;
|
||||
if ((ULONG)SectionHandle & 1) Flags |= PROCESS_CREATE_FLAGS_BREAKAWAY;
|
||||
if ((ULONG)DebugPort & 1) Flags |= PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT;
|
||||
if (InheritObjectTable) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES;
|
||||
|
||||
/* Call the new API */
|
||||
return NtCreateProcessEx(ProcessHandle,
|
||||
|
|
|
@ -143,9 +143,13 @@ static NTSTATUS
|
|||
RemoveConsoleByHandle(IN HANDLE Handle)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG Index = HandleToULong(Handle) >> 2;
|
||||
PCONSOLE Console;
|
||||
|
||||
BOOLEAN ValidHandle = ((HandleToULong(Handle) & 0x3) == 0x3);
|
||||
ULONG Index = HandleToULong(Handle) >> 2;
|
||||
|
||||
if (!ValidHandle) return STATUS_INVALID_HANDLE;
|
||||
|
||||
ASSERT( (ConsoleList == NULL && ConsoleListSize == 0) ||
|
||||
(ConsoleList != NULL && ConsoleListSize != 0) );
|
||||
|
||||
|
@ -339,10 +343,13 @@ ConDrvValidateConsole(OUT PCONSOLE* Console,
|
|||
IN BOOLEAN LockConsole)
|
||||
{
|
||||
BOOLEAN RetVal = FALSE;
|
||||
|
||||
ULONG Index = HandleToULong(ConsoleHandle) >> 2;
|
||||
PCONSOLE ValidatedConsole;
|
||||
|
||||
BOOLEAN ValidHandle = ((HandleToULong(ConsoleHandle) & 0x3) == 0x3);
|
||||
ULONG Index = HandleToULong(ConsoleHandle) >> 2;
|
||||
|
||||
if (!ValidHandle) return FALSE;
|
||||
|
||||
if (!Console) return FALSE;
|
||||
*Console = NULL;
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ VOID FASTCALL
|
|||
ConSrvReleaseConsole(PCONSOLE Console,
|
||||
BOOL WasConsoleLocked)
|
||||
{
|
||||
/* Just call the driver*/
|
||||
/* Just call the driver */
|
||||
ConDrvReleaseConsole(Console, WasConsoleLocked);
|
||||
}
|
||||
|
||||
|
|
|
@ -387,6 +387,8 @@ ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
|
|||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
ASSERT(ProcessData->HandleTable);
|
||||
// ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
|
||||
// (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
|
||||
|
||||
if (Index >= ProcessData->HandleTableSize ||
|
||||
(Object = ProcessData->HandleTable[Index].Object) == NULL)
|
||||
|
@ -781,6 +783,9 @@ CSR_API(SrvVerifyConsoleIoHandle)
|
|||
|
||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
// ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
|
||||
// (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
|
||||
|
||||
if (!IsConsoleHandle(ConsoleHandle) ||
|
||||
Index >= ProcessData->HandleTableSize ||
|
||||
ProcessData->HandleTable[Index].Object == NULL)
|
||||
|
@ -816,6 +821,9 @@ CSR_API(SrvDuplicateHandle)
|
|||
|
||||
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
|
||||
|
||||
// ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
|
||||
// (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
|
||||
|
||||
if ( /** !IsConsoleHandle(ConsoleHandle) || **/
|
||||
Index >= ProcessData->HandleTableSize ||
|
||||
(Entry = &ProcessData->HandleTable[Index])->Object == NULL)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue