[C] File Lock Key?

AceInfinity

Emeritus, Contributor
Joined
Feb 21, 2012
Posts
1,728
Location
Canada
Anyone know any information about retrieving a file lock key set by NtLockFile()? I need to retrieve a pointer to this value, but I am a bit confused on where this would be stored if I don't have a prior reference to it? (Not being the one to call NtLockFile() in the first place).

Here is a bit of relevant code:
Code:
[NO-PARSE]#include <Windows.h>

#undef __STRICT_ANSI__
#include <stdio.h>
#include <stdlib.h>
#include <io.h>

#define NTSTATUS ULONG
#define STATUS_SUCCESS          0x00000000
#define STATUS_RANGE_NOT_LOCKED 0xC000007E
#define NTDLL GetModuleHandle("ntdll.dll")

// NTSTATUS NtUnlockFile(
//   IN HANDLE FileHandle,
//   OUT PIO_STATUS_BLOCK IoStatusBlock,
//   IN PLARGE_INTEGER ByteOffset,
//   IN PLARGE_INTEGER Length,
//   IN PULONG Key
// );

typedef struct _IO_STATUS_BLOCK
{
  union
  {
    LONG Status;
    PVOID Pointer;
  };
  ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

void usage(const char *arg0)
{
  const char *ptr_slash = strchr(arg0, '\\');
  const char *bin = ptr_slash == NULL ? arg0 : strrchr(arg0, '\\') + 1;
  fprintf(stderr,
    "\tUsage: %s [file-path]\n"
    "\t- Example: %s \"C:\\documents\\file.png\"\n"
    , bin, bin);
  getchar();
}

int main(int argc, char const *argv[])
{
  if (argc < 2)
  {
    usage(argv[0]);
    exit(1);
  }

  NTSTATUS(*NtUnlockFile)(
    /* IN */  HANDLE           /* file handle */,
    /* OUT */ PIO_STATUS_BLOCK /* io_status_block */,
    /* IN */  PLARGE_INTEGER   /* byte offset */,
    /* IN */  PLARGE_INTEGER   /* length */,
    /* IN */  PULONG           /* key */
  ) = (NTSTATUS(*)(HANDLE, PIO_STATUS_BLOCK, PLARGE_INTEGER, PLARGE_INTEGER, PULONG)) GetProcAddress(NTDLL, "NtUnlockFile");
  if (NtUnlockFile == NULL)
  {
    fprintf(stderr, "Error - Could not get a function pointer to NtUnlockFile().\n");
    getchar();
    exit(1);
  }

  FILE *file = fopen(argv[1], "rb");
  if (file == NULL)
  {
    fprintf(stderr, "Error - Could not open file.\n");
    getchar();
    exit(1);
  }

  int fd = _fileno(file);
  HANDLE file_handle = (HANDLE) _get_osfhandle(fd);

  IO_STATUS_BLOCK io;
  LARGE_INTEGER byte_offset; byte_offset.QuadPart = 0;
  LARGE_INTEGER length; length.QuadPart = lseek(fd, 0, SEEK_END) + 1;

  ULONG *lock_key = NULL; // -- TODO
  NTSTATUS ret = NtUnlockFile(file_handle, &io, &byte_offset, &length, lock_key);
  _close(fd);
  if (ret != STATUS_SUCCESS)
  {
    if (ret == STATUS_RANGE_NOT_LOCKED)
      fprintf(stderr, "Error - The range specified in NtUnlockFile was not locked."
              "\n\tNTSTATUS code: [0x%.8X].\n", ret);
    else
      fprintf(stderr, "Error - NtUnlockFile() failed with NTSTATUS code: [0x%.8X]\n", ret);
    getchar();
    exit(1);
  }
  fprintf(stdout, "Success!\n");
  getchar();
}[/NO-PARSE]

I get a return of STATUS_RANGE_NOT_LOCKED, but I'm not sure if that is because I don't have the appropriate key or whether the way I'm going about the range is not proper.
 
Hi Ace,

Programming aside, I'm assuming you already are aware that the return value of SRNL implies your specified byte range is not locked?
 
Hi Ace,

Programming aside, I'm assuming you already are aware that the return value of SRNL implies your specified byte range is not locked?

Yes, but that's my point. I wonder if I'm:

a) Not specifying the proper range for use by NtUnlockFile(), or...
b) Whether the lock state of the file, returned in the NTSTATUS code is determined by the key (if there is supposed to be one)

I had an exclusive lock on a file through a dummy program, so unless this isn't the kind of lock that this function evaluates, it *should* have in theory been locked. It was a dll that I called to load from another process. I still haven't found any guidance though on how to determine a pointer to the 4 byte value to the lock key though, which is something I'll eventually want to figure out. I just don't know if it's relevant to solving this particular problem or not yet.

The other thing is determining the proper or most significant range for the lock.
 
Last edited:
Ace, as a side note - you can always try to steal the handle to the locked file from the process holding it (via duplicatehandleex) and then try to close it.

m.
 
Ace, as a side note - you can always try to steal the handle to the locked file from the process holding it (via duplicatehandleex) and then try to close it.

m.

Yeah, but this still doesn't demonstrate how the original handle to the lock is obtained in the first place. I can't duplicate what I can't find--that's my main issue at this point... Thanks for the help though. :) There's very little in the way of this lock key in terms of documentation that I've found so far. It's a 4 byte key that I need to get a pointer to. Perhaps the only way is to fool around with NtLockFile() and do some investigation...
 
Last edited:

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top