Example #1
0
/* Attempt to impersonate a client and open a file for the filedisk. */
static NTSTATUS STDCALL WvFilediskOpen_(
    IN WV_SP_FILEDISK_T filedisk,
    IN PANSI_STRING file_path
  ) {
    WV_S_FILEDISK_OPENER_ opener;

    /* Allocate and convert the file path from ANSI to Unicode. */
    opener.status = RtlAnsiStringToUnicodeString(
        opener.file_path,
        file_path,
        TRUE
      );
    if (!NT_SUCCESS(opener.status)) {
        DBG("Couldn't allocate Unicode file path!\n");
        goto err_ansi_to_unicode;
      }

    /* Build the impersonation context. */
    opener.status = WvFilediskCreateClientSecurity(&filedisk->impersonation);
    if (!NT_SUCCESS(opener.status)) {
        DBG("Couldn't build impersonation context!\n");
        goto err_impersonation;
      }

    /* Build the rest of the work item. */
    opener.item->Func = WvFilediskOpenInThread_;
    opener.filedisk = filedisk;
    KeInitializeEvent(opener.completion, SynchronizationEvent, FALSE);

    /* Attempt to open the file from within the filedisk's thread. */
    if (!(WvlThreadAddItem(filedisk->Thread, opener.item))) {
        DBG("Filedisk thread not active!\n");
        goto err_add_item;
      }
    KeWaitForSingleObject(
        opener.completion,
        Executive,
        KernelMode,
        FALSE,
        NULL
      );
    /* Fall through to free resources and return status. */

    err_add_item:

    err_impersonation:

    RtlFreeUnicodeString(opener.file_path);
    err_ansi_to_unicode:

    return opener.status;
  }
Example #2
0
/* The thread responsible for hot-swapping filedisks. */
static VOID STDCALL WvFilediskHotSwapThread_(IN OUT WVL_SP_THREAD_ITEM item) {
    LARGE_INTEGER timeout;
    WVL_SP_THREAD thread = CONTAINING_RECORD(item, WVL_S_THREAD, Main);
    WVL_SP_THREAD_ITEM work_item;
    WV_SP_FILEDISK_HOT_SWAPPER_ info;

    /* Wake up at least every 10 seconds. */
    timeout.QuadPart = -100000000LL;

    while (
        (thread->State == WvlThreadStateStarted) ||
        (thread->State == WvlThreadStateStopping)
      ) {
        /* Wait for the work signal or the timeout. */
        KeWaitForSingleObject(
            &thread->Signal,
            Executive,
            KernelMode,
            FALSE,
            &timeout
          );

        work_item = WvlThreadGetItem(thread);
        if (!work_item)
          continue;

        if (work_item->Func != WvFilediskHotSwapThread_) {
            DBG("Unknown work item.\n");
            continue;
          }
        info = CONTAINING_RECORD(
            work_item,
            WV_S_FILEDISK_HOT_SWAPPER_,
            item[0]
          );
        /* Attempt a hot swap. */
        if (WvFilediskHotSwap_(info->filedisk, info->filename)) {
            /* Success. */
            RtlFreeUnicodeString(info->filename);
            wv_free(info);
          } else {
            /* Re-enqueue. */
            WvlThreadAddItem(thread, info->item);
          }

        /* Reset the work signal. */
        KeResetEvent(&thread->Signal);
      } /* while thread is running. */
    return;
  }
Example #3
0
/**
 * Initiate a filedisk hot-swap to another file.
 *
 * @v filedisk          The filedisk to be hot-swapped.
 * @v file              The ANSI filename for swapping to.
 */
VOID STDCALL WvFilediskHotSwap(IN WV_SP_FILEDISK_T filedisk, IN PCHAR file) {
    static WVL_S_THREAD thread = {
        /* Main */
        {
            /* Link */
            {0},
            /* Func */
            WvFilediskHotSwapThread_,
          },
        /* State */
        WvlThreadStateNotStarted,
      };
    WV_SP_FILEDISK_HOT_SWAPPER_ hot_swapper;
    ANSI_STRING file_ansi;
    NTSTATUS status;

    hot_swapper = wv_malloc(sizeof *hot_swapper);
    if (!hot_swapper) {
        DBG("Non-critical: Couldn't allocate work item.\n");
        return;
      }
    /* Build the Unicode string. */
    RtlInitAnsiString(&file_ansi, file);
    hot_swapper->filename->Buffer = NULL;
    status = RtlAnsiStringToUnicodeString(
        hot_swapper->filename,
        &file_ansi,
        TRUE
      );
    if (!NT_SUCCESS(status)) {
        DBG("Non-critical: Couldn't allocate unicode string.\n");
        wv_free(hot_swapper);
        return;
      }
    /* Build the rest of the work item. */
    hot_swapper->item->Func = WvFilediskHotSwapThread_;
    hot_swapper->filedisk = filedisk;
    /* Start the thread.  If it's already been started, no matter. */
    WvlThreadStart(&thread);
    /* Add the hot-swapper work item. */
    if (!WvlThreadAddItem(&thread, hot_swapper->item)) {
        DBG("Non-critical: Couldn't add work item.\n");
        RtlFreeUnicodeString(hot_swapper->filename);
        wv_free(hot_swapper);
      }
    /* The thread is responsible for freeing the work item and file path. */
    return;
  }
Example #4
0
/**
 * Initiate a search for a GRUB4DOS backing disk.
 *
 * @v filedisk          The filedisk whose backing disk we need.
 */
static BOOLEAN STDCALL WvFilediskG4dFindBackingDisk(
    IN WV_SP_FILEDISK_T filedisk
  ) {
    SP_WV_FILEDISK_G4D_FIND_BACKING_DISK finder;
    KIRQL irql;

    finder = wv_malloc(sizeof *finder);
    if (!finder) {
        DBG("Couldn't allocate work item!\n");
        goto err_finder;
      }

    KeAcquireSpinLock(&WvFindDiskLock, &irql);
    ++WvFindDisk;
    KeReleaseSpinLock(&WvFindDiskLock, irql);

    finder->item->Func = WvFilediskG4dFindBackingDisk_;
    finder->filedisk = filedisk;
    /* Add the hot-swapper work item. */
    if (!WvlThreadAddItem(filedisk->Thread, finder->item)) {
        DBG("Couldn't add work item!\n");
        goto err_work_item;
      }

    /* The thread is responsible for freeing the work item. */
    return TRUE;

    err_work_item:

    KeAcquireSpinLock(&WvFindDiskLock, &irql);
    --WvFindDisk;
    KeReleaseSpinLock(&WvFindDiskLock, irql);

    wv_free(finder);
    err_finder:

    return FALSE;
  }