22using System . Collections . Generic ;
33using System . IO ;
44using System . Linq ;
5- using System . Runtime . InteropServices ;
65using System . Text . Json ;
6+ using Sandbox . Utility ;
77
88namespace Sandbox . SolutionGenerator
99{
@@ -26,87 +26,26 @@ private string NormalizePath( string path )
2626 return path . Replace ( '\\ ' , '/' ) ;
2727 }
2828
29-
30- // Importing necessary Win32 APIs for getting the canonical path
31- [ DllImport ( "kernel32.dll" , CharSet = CharSet . Unicode , SetLastError = true ) ]
32- private static extern IntPtr CreateFileW ( string lpFileName , uint dwDesiredAccess , uint dwShareMode , IntPtr lpSecurityAttributes , uint dwCreationDisposition , uint dwFlagsAndAttributes , IntPtr hTemplateFile ) ;
33-
34- [ DllImport ( "kernel32.dll" , CharSet = CharSet . Unicode , SetLastError = true ) ]
35- private static extern uint GetFinalPathNameByHandleW ( IntPtr hFile , char [ ] lpszFilePath , uint cchFilePath , uint dwFlags ) ;
36-
37- [ DllImport ( "kernel32.dll" , SetLastError = true ) ]
38- private static extern bool CloseHandle ( IntPtr hObject ) ;
39-
40- // Define magic numbers with proper names
41- private const uint FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 ;
42- private const uint OPEN_EXISTING = 3 ;
43- private const uint FILE_SHARE_READ = 1 ;
44- private const uint FILE_SHARE_WRITE = 2 ;
45-
46- /// <summary>
47- /// Get the proper path casing for the given path
48- /// </summary>
49- private static string GetCanonicalPath ( string path )
50- {
51- if ( ! string . IsNullOrWhiteSpace ( path ) && ! Path . IsPathRooted ( path ) ) return path ;
52-
53- try
54- {
55- var handle = CreateFileW ( path , 0 , FILE_SHARE_READ | FILE_SHARE_WRITE , IntPtr . Zero , OPEN_EXISTING , FILE_FLAG_BACKUP_SEMANTICS , IntPtr . Zero ) ;
56- if ( handle == IntPtr . Zero || handle == new IntPtr ( - 1 ) )
57- return path ;
58-
59- try
60- {
61- var buffer = new char [ 512 ] ;
62- var len = GetFinalPathNameByHandleW ( handle , buffer , ( uint ) buffer . Length , 0 ) ;
63- if ( len > 0 && len < buffer . Length )
64- {
65- var finalPath = new string ( buffer , 0 , ( int ) len ) ;
66- // Remove the \\?\ prefix added by Windows API
67- if ( finalPath . StartsWith ( @"\\?\" ) )
68- {
69- finalPath = finalPath . Substring ( 4 ) ;
70- }
71- return finalPath ;
72- }
73- else
74- {
75- return path ;
76- }
77- }
78- finally
79- {
80- CloseHandle ( handle ) ;
81- }
82- }
83- catch
84- {
85- // Ignore errors and return original path
86- return path ;
87- }
88- }
89-
9029 /// <summary>
9130 /// Converts a path to be relative to a base path, always returning forward slashes.
9231 /// </summary>
9332 private string AttemptAbsoluteToRelative ( string basePath , string targetPath )
9433 {
9534 string targetFileName = string . Empty ;
96- string baseDir = GetCanonicalPath ( basePath ) ;
97- string targetDir = GetCanonicalPath ( targetPath ) ;
35+ string baseDir = NativeFileSystem . GetCanonicalPath ( basePath ) ;
36+ string targetDir = NativeFileSystem . GetCanonicalPath ( targetPath ) ;
9837
9938 // If target is a file, extract the filename
10039 if ( Path . HasExtension ( targetPath ) )
10140 {
10241 targetFileName = Path . GetFileName ( targetPath ) ;
103- targetDir = GetCanonicalPath ( Path . GetDirectoryName ( targetPath ) ?? targetPath ) ;
42+ targetDir = NativeFileSystem . GetCanonicalPath ( Path . GetDirectoryName ( targetPath ) ?? targetPath ) ;
10443 }
10544
10645 // If base is a file, use its directory
10746 if ( Path . HasExtension ( basePath ) )
10847 {
109- baseDir = GetCanonicalPath ( Path . GetDirectoryName ( basePath ) ?? basePath ) ;
48+ baseDir = NativeFileSystem . GetCanonicalPath ( Path . GetDirectoryName ( basePath ) ?? basePath ) ;
11049 }
11150
11251 // Calculate relative path from base to target - this preserves casing when inputs are cased
0 commit comments