Its not a supported OS in the sense that there is no new development for it, or efforts to really extend or fully support a quality life cycle with dedicated resources like for current OS versions, via MS. Its basically only supported for important fixes but not all fixes and tech-type support in some cases, and those aren't even having resources devoted to them on a dedicated basis. So "supported" is really only a matter of public preception and use of the term "supported", and thats what MS gave people - the preception of support without devoting dedicated resources as they do for current OS versions that are really life (quality) cycle supported. Its more "life support" than "life quality" support. XP is at the end of its life cycle, has been, and now its just on life support to prolong the inevitable. In short, support only really exists in terms of the use of the word 'support'.
@jassing:
Anyway, Junctions....what you want to look at is reparse points, don't remember if you can use reparse points in XP or not - this might give you some ideas > Convert the C++ to PB, not too difficult (the Reparse Points and Directory Junctions section at the link), from >
http://www.flexhex.com/docs/articles/hard-links.phtml < and once again, remember, NTFS only for true junctions (NTFS - version 5 or greater). Also keep in mind that junctions are useless for things that are transitory, meaning if it can be moved, removed, changed, or re-allocated, that the junction will be useless plus junctions can't point to a mapped network object (well, they aren't supposed to anyway even though there is a way to make them do so) or link to files without a file system filter driver. Junctions (not created as hard links) are actually a less advanced soft link. A shortcut (which is a soft link also) is a form of a more "advanced version" of the junction soft link, and is more fexible and usable than a junction and can do things a junction can't and is not limited to just NTFS.
here is some, "quasi-psuedo code" quickly cobbled together (although some of it does work) to help you get started on the conversion - I have not tried it and don't know if it really works or not but just wanted to give you some ideas to help you get started on the conversion but it should be kinda close in a way, use at your own risk
Code: Select all
; creating a directory junction - direct quick quasi-psuedo code conversion to PB from http://www.flexhex.com/docs/articles/hard-links.phtml and is not intended to be correct or used as is
#SE_BACKUP_NAME$ = "SeBackupPrivilege"
#SE_RESTORE_NAME$ = "SeRestorePrivilege"
#IO_REPARSE_TAG_MOUNT_POINT = $A0000003L
#REPARSE_MOUNTPOINT_HEADER_SIZE = 8
#FILE_FLAG_OPEN_REPARSE_POINT = $00200000
Structure REPARSE_MOUNTPOINT_DATA_BUFFER
ReparseTag.i
ReparseDataLength.i
Reserved.w
ReparseTargetLength.w
ReparseTargetMaximumLength.w
Reserved1.w
ReparseTarget.w[1]
EndStructure
Procedure.b IsPrivilegeEnabled(Privilege.s)
Protected hToken.i, PrvEnb.b, TokenPriv.PRIVILEGE_SET
Protected FuncRet.i, PChkRes.i
hToken = 0
PChkRes = #False
FuncRet = OpenThreadToken_(GetCurrentThread(), #TOKEN_QUERY, #False, @Token)
If FuncRet = 0 And GetLastError_() = #ERROR_NO_TOKEN
FuncRet = OpenProcessToken_(GetCurrentProcess_(), #TOKEN_QUERY, @hToken)
If FuncRet <> 0
TokenPriv\PrivilegeCount = 1
TokenPriv\Control = 0
FuncRet = LookupPrivilegeValue_(#Null, @Privilege, @TokenPriv\Privilege[0]\Luid)
If FuncRet <> 0
PChkRes = PrivilegeCheck_(hToken, @TokenPriv, @PrvEnb) And PrvEnb
Else
PrvEnb = #False
EndIf
Else
PrvEnb = #False
EndIf
EndIf
CloseHandle_(hToken)
ProcedureReturn PrvEnb
EndProcedure
Procedure.b Enable_Privilege(priv.s)
Protected TokenPriv.TOKEN_PRIVILEGES, token.i
Protected hToken.i, ProcRet.b, FuncRet.i
ProcRet = #False
FuncRet = OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES, @hToken)
If FuncRet <> #False
TokenPriv\PrivilegeCount = 1
FuncRet = LookupPrivilegeValue_(#Null, @priv, @TokenPriv\Privileges[0]\Luid)
TokenPriv\Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
If FuncRet <> #False
FuncRet = AdjustTokenPrivileges_(hToken, #False, @TokenPriv, SizeOf(TokenPriv), #Null, #Null)
token = CloseHandle_(hToken)
If FuncRet <> #False
ProcRet = #True
Else
ProcRet = #False
EndIf
Else
ProcRet = #False
EndIf
Else
ProcRet = #False
EndIf
If token <> 0
CloseHandle_(hToken)
EndIf
ProcedureReturn ProcRet
EndProcedure
;pszPath = our created directory path
Procedure OpenDirectory(pszPath.s, bReadWrite.b)
Protected hDir.i
;;// Obtain backup/Restore privilege in case we don't have it
Enable_Privilege(#SE_RESTORE_NAME$)
Enable_Privilege(#SE_BACKUP_NAME$)
If IsPrivilegeEnabled(#SE_RESTORE_NAME$) = #True And IsPrivilegeEnabled(#SE_BACKUP_NAME$) = #True
dwAccess.i = #GENERIC_READ | #GENERIC_WRITE
hDir = CreateFile_(pszPath, dwAccess, 0, #Null, #OPEN_EXISTING, #FILE_FLAG_OPEN_REPARSE_POINT | #FILE_FLAG_BACKUP_SEMANTICS, #Null)
Else
hDir = #False
EndIf
ProcedureReturn hDir
EndProcedure
; step 1: creating a directory if it does not exists. If the directory exists, it must be empty - you cannot associate a reparse point with a non-empty directory.
; Note that szTarget string must contain the path prefixed with the "non-parsed" prefix "\??\", and terminated with the backslash character, for example "\??\C:\Some Dir\".
; szJunction = The path of the directory to be created, e.g. szJunction.s = ""\??\C:\Some Dir\"
CreateDirectory_(szJunction, #Null)
; step 2 = get a handle the the created directory
hDir = OpenDirectory(szJunction, #True)
If hDir > 0
*ReparseBuffer.REPARSE_MOUNTPOINT_DATA_BUFFER
*ReparseBuffer = AllocateMemory(SizeOf(REPARSE_MOUNTPOINT_DATA_BUFFER) + #MAX_PATH * SizeOf(WCHAR))
; step 3 = where the magic happens
;; Prepare reparse point Data
;memset(buf, 0, SizeOf(buf));
*ReparseBuffer\ReparseTag = #IO_REPARSE_TAG_MOUNT_POINT
len.i = MultiByteToWideChar_(#CP_ACP, 0, szJunction, -1, *ReparseBuffer\ReparseTarget, #MAX_PATH)
*ReparseBuffer\ReparseTargetMaximumLength = len * SizeOf(WCHAR)
*ReparseBuffer\ReparseTargetLength = len * SizeOf(WCHAR)
*ReparseBuffer\ReparseDataLength = *ReparseBuffer\ReparseTarget + 12
;;// Attach reparse point
dwRet.i
DeviceIoControl_(hDir, #FSCTL_SET_REPARSE_POINT, *ReparseBuffer, *ReparseBuffer\ReparseDataLength + #REPARSE_MOUNTPOINT_HEADER_SIZE, #Null, 0, @dwRet, #Null) ; this function call and parameters causes the reparse point to be set
Else
Debug "can't get handle to directory"
EndIf
the #FSCTL_SET_REPARSE_POINT is defined like this in the SDK headers:
Code: Select all
#define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) // REPARSE_DATA_BUFFER
so you need to figure out how that FSCTL_SET_REPARSE_POINT constant translates to PB use
In addition there is also this article at Code Project you can get some hints from for conversion to PB >
http://www.codeproject.com/Articles/194 ... ion-Points d/l the soure code project and convert it
Something else that may give you some ideas > NTFS Links extends Microsoft Windows XP operating system shell by adding additional features related to soft and hard links supported by NTFS file system. >
http://alax.info/blog/ntfslinks which is basically a re-warmed version of this >
http://elsdoerfer.name/ntfslink but for the second link the source code is avaialble.
Too bad though your not using Vista or Windows 7 as all it is then is just a call to the CreateSymbolicLink() function and its done because symbolic links are essentially the same thing as junctions and use the same reparse points method to create the symbolic link.
There is a way to create a "fake" junction by creation of an .ini file, but this isn't a real junction and can cause problems, but in case you'd like to know its outlined here >
http://www.techrepublic.com/article/man ... xp/5388706