Coverage for sources/mimeogram/fsprotect/windows.py: 80%

71 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-05 19:15 +0000

1# vim: set filetype=python fileencoding=utf-8: 

2# -*- coding: utf-8 -*- 

3 

4#============================================================================# 

5# # 

6# Licensed under the Apache License, Version 2.0 (the "License"); # 

7# you may not use this file except in compliance with the License. # 

8# You may obtain a copy of the License at # 

9# # 

10# http://www.apache.org/licenses/LICENSE-2.0 # 

11# # 

12# Unless required by applicable law or agreed to in writing, software # 

13# distributed under the License is distributed on an "AS IS" BASIS, # 

14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

15# See the License for the specific language governing permissions and # 

16# limitations under the License. # 

17# # 

18#============================================================================# 

19 

20 

21''' Sensitive filesystem locations on Windows. ''' 

22 

23 

24from . import __ 

25 

26 

27_scribe = __.produce_scribe( __name__ ) 

28 

29 

30CSIDL_PROGRAM_FILES_COMMON = 0x002b # C:\Program Files\Common Files 

31CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c # C:\Program Files (x86)\Common Files 

32 

33 

34def discover_system_paths( ) -> frozenset[ __.Path ]: 

35 ''' Discovers system paths via standard Windows mechanisms. ''' 

36 paths: set[ __.Path ] = set( ) 

37 paths.update( _discover_system_paths_via_environment( ) ) 

38 paths.update( _discover_system_paths_via_api( ) ) 

39 # TODO? Cygwin 

40 if _detect_mingw( ): _discover_add_mingw_system_paths( paths ) 

41 return frozenset( paths ) 

42 

43 

44def _detect_mingw( ) -> bool: 

45 ''' Checks if running in MinGW environment. ''' 

46 # TODO: If environment vars are not set, then return False. 

47 # Else, proceed to more expensive checck to ensure sane MinGW. 

48 mingw_env = __.os.environ.get( 'MSYSTEM', '' ) 

49 if mingw_env.startswith( ('MINGW', 'MSYS') ): 49 ↛ 52line 49 didn't jump to line 52 because the condition on line 49 was always true

50 _scribe.debug( f'MinGW detected via MSYSTEM={mingw_env}' ) 

51 return True 

52 mingw_paths = ( '/mingw32', '/mingw64', '/msys', '/usr/bin/msys-2.0.dll' ) 

53 for path in mingw_paths: 

54 if not __.Path( path ).exists( ): continue 

55 _scribe.debug( f'MinGW detected via path: {path}' ) 

56 return True 

57 return False 

58 

59 

60def _discover_add_mingw_system_paths( paths: set[ __.Path ] ) -> None: 

61 paths_: set[ __.Path ] = set( ) 

62 for path in paths: 

63 parts = path.parts 

64 if 1 >= len( parts ): continue 64 ↛ 62line 64 didn't jump to line 62 because the continue on line 64 wasn't executed

65 drive = parts[ 0 ][ 0 ].lower( ) # TODO? Consider UNC paths. 

66 paths_.add( __.Path( f"/{drive}" ).joinpath( *parts[ 1 : ] ) ) 

67 _scribe.debug( 

68 "Calculated {} MingGW system paths.".format( len( paths_ ) ) ) 

69 paths_.update( map( 

70 __.Path, 

71 ( '/bin', '/dev', '/etc', 

72 '/mingw32', '/mingw64', '/msys', '/proc', '/usr', 

73 ) ) ) 

74 paths.update( paths_ ) 

75 

76 

77def _discover_system_paths_via_environment( ) -> frozenset[ __.Path ]: 

78 ''' Discovers system paths via environment. ''' 

79 environ = __.os.environ 

80 paths: set[ __.Path ] = set( ) 

81 system_drive = environ.get( 'SystemDrive', 'C:' ) 

82 system_root = environ.get( 'SystemRoot', f"{system_drive}\\Windows" ) 

83 paths.add( __.Path( system_root ) ) 

84 paths.add( __.Path( f"{system_drive}/System Volume Information" ) ) 

85 # Program Files variations 

86 progfiles = __.os.environ.get( 

87 'ProgramFiles', f"{system_drive}\\Program Files" ) 

88 paths.add( __.Path( progfiles ) ) 

89 for progfiles_ename in ( 

90 'ProgramFiles(x86)', 'ProgramFiles(Arm)', 'ProgramW6432' 

91 ): 

92 progfiles = environ.get( progfiles_ename ) 

93 if progfiles: paths.add( __.Path( progfiles ) ) 

94 return frozenset( paths ) 

95 

96 

97def _discover_system_paths_via_api( ) -> set[ __.Path ]: 

98 ''' Discovers system paths via API. ''' 

99 import ctypes 

100 from ctypes.wintypes import MAX_PATH 

101 dmessage = "Could not retrieve additional Windows system paths via API." 

102 paths: set[ __.Path ] = set( ) 

103 try: dll = ctypes.windll.shell32 # pyright: ignore 

104 except Exception: 

105 _scribe.debug( dmessage ) 

106 buf = ctypes.create_unicode_buffer( MAX_PATH + 1 ) 

107 for key in ( 

108 CSIDL_PROGRAM_FILES_COMMON, 

109 CSIDL_PROGRAM_FILES_COMMONX86, 

110 ): 

111 try: 

112 dll.SHGetFolderPathW( # pyright: ignore 

113 None, key, None, 0, buf ) 

114 paths.add( __.Path( buf.value ) ) 

115 except Exception: # noqa: PERF203 

116 _scribe.debug( dmessage ) 

117 return paths 

118 

119 

120def discover_user_paths( ) -> frozenset[ __.Path ]: 

121 ''' Discovers Windows user-specific paths that should be protected. ''' 

122 paths: set[ __.Path ] = set( ) 

123 appdata = __.os.environ.get( 'APPDATA' ) 

124 local_appdata = __.os.environ.get( 'LOCALAPPDATA' ) 

125 userprofile = __.os.environ.get( 'USERPROFILE' ) 

126 if appdata: paths.add( __.Path( appdata ) ) 

127 if local_appdata: paths.add( __.Path( local_appdata ) ) 

128 if userprofile: 128 ↛ 138line 128 didn't jump to line 138 because the condition on line 128 was always true

129 profile = __.Path( userprofile ) 

130 paths.update( ( 

131 profile / 'AppData' / 'Local', 

132 profile / 'AppData' / 'LocalLow', 

133 profile / 'AppData' / 'Roaming', 

134 # Legacy Paths 

135 profile / 'Application Data', 

136 profile / 'Local Settings', 

137 ) ) 

138 return frozenset( paths )