37. FAQ o Win API

Q> How to create hard link on NTFS? 
A> 

#include <windows.h> 
#include <stdio.h> 
#pragma hdrstop 
#define err doerr (__ FILE __, __ LINE __) 

void doerr (const char *file, int line) 
{ 
 DWORD e; 

 e = GetLastError (); 
 if (e == 0) 
  return; 

 printf ("%s (%d): gle = %lu\n", file, line, e); 
 exit (2); 
}

void enableprivs () 
{ 
 HANDLE hToken; 
 byte buf [sizeof TOKEN_PRIVILEGES * 2]; 
 TOKEN_PRIVILEGES AND tkp = * ((TOKEN_PRIVILEGES *) buf); 

 if (! OpenProcessToken (GetCurrentProcess (), 
  TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 
  err; 

 //we take SeBackupPrivilege and SeRestorePrivilege 

 if (! LookupPrivilegeValue (NULL, SE_BACKUP_NAME, &tkp.Privileges [0].Luid)) 
  err; 

 if (! LookupPrivilegeValue (NULL, SE_RESTORE_NAME, &tkp.Privileges [1].Luid)) 
  err; 

 tkp. PrivilegeCount = 2; 
 tkp. Privileges [0].Attributes = SE_PRIVILEGE_ENABLED; 
 tkp. Privileges [1].Attributes = SE_PRIVILEGE_ENABLED; 

 AdjustTokenPrivileges (hToken, FALSE, &tkp, sizeof tkp, 
  NULL, NULL); 
}

int main (int argc, char *argv []) 
{ 
 HANDLE fh; 

 if (argc! = 3) 
 { 
 printf ("usage: lnw {file} {new_link_name} \n"); 
 return 1; 
 }
 enableprivs (); 

 fh = CreateFile (argv [1], GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 
  FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS, NULL); 
 if (fh == INVALID_HANDLE_VALUE || fh == NULL) err; 

 static char buf1 [MAX_PATH]; 
 static wchar_t buf2 [MAX_PATH * 2]; 
 char *p; 
 void *ctx = NULL; 
 WIN32_STREAM_ID wsi; 
 DWORD numwritten; 

 GetFullPathName (argv [2], MAX_PATH, &buf1 [0], &p); 

 wsi.dwStreamId = BACKUP_LINK; 
 wsi.dwStreamAttributes = 0; 
 wsi.dwStreamNameSize = 0; 
 wsi. Size. QuadPart = strlen (buf1) * 2 + 2; 
 MultiByteToWideChar (CP_ACP, 0, buf1, strlen (buf1) + 1, buf2, MAX_PATH); 

 if (! BackupWrite (fh, (byte *) &wsi, 20, &numwritten, FALSE, FALSE, &ctx) 
)err; 
 if (numwritten! = 20) err; 

 if (! BackupWrite (fh, (byte *) buf2, wsi. Size. LowPart, &numwritten, FALSE, 
FALSE, &ctx)) err; 
 if (numwritten! = wsi. Size. LowPart) err; 

 BackupWrite (fh, (byte *) &buf1 [0], 0, &numwritten, TRUE, FALSE, &ctx); 
 CloseHandle (fh); 
 return 0; 
}

2000 (c) DM