Exemplo n.º 1
0
/*
 * UserUnloadKbl
 *
 * Unloads specified Keyboard Layout if possible
 */
BOOL
UserUnloadKbl(PKL pKl)
{
    /* According to msdn, UnloadKeyboardLayout can fail
       if the keyboard layout identifier was preloaded. */
    if (pKl == gspklBaseLayout)
    {
        if (pKl->pklNext == pKl->pklPrev)
        {
            /* There is only one layout */
            return FALSE;
        }

        /* Set next layout as default */
        gspklBaseLayout = pKl->pklNext;
    }

    if (pKl->head.cLockObj > 1)
    {
        /* Layout is used by other threads */
        pKl->dwKL_Flags |= KLF_UNLOAD;
        return FALSE;
    }

    /* Unload the layout */
    pKl->pklPrev->pklNext = pKl->pklNext;
    pKl->pklNext->pklPrev = pKl->pklPrev;
    UnloadKbdFile(pKl->spkf);
    UserDeleteObject(pKl->head.h, TYPE_KBDLAYOUT);
    return TRUE;
}
Exemplo n.º 2
0
static
BOOL
FASTCALL
RemoveTimer(PTIMER pTmr)
{
  BOOL Ret = FALSE;
  if (pTmr)
  {
     /* Set the flag, it will be removed when ready */
     RemoveEntryList(&pTmr->ptmrList);
     if ((pTmr->pWnd == NULL) && (!(pTmr->flags & TMRF_SYSTEM))) // System timers are reusable.
     {
        UINT_PTR IDEvent;

        IDEvent = NUM_WINDOW_LESS_TIMERS - pTmr->nID;
        IntLockWindowlessTimerBitmap();
        RtlClearBit(&WindowLessTimersBitMap, IDEvent);
        IntUnlockWindowlessTimerBitmap();
     }
     UserDereferenceObject(pTmr);
     Ret = UserDeleteObject( UserHMGetHandle(pTmr), otTimer);
  }
  if (!Ret) ERR("Warning: Unable to delete timer\n");

  return Ret;
}
Exemplo n.º 3
0
/*
 * UserLoadKbdLayout
 *
 * Loads keyboard layout and creates KL object
 */
static PKL
UserLoadKbdLayout(PUNICODE_STRING pwszKLID, HKL hKL)
{
    LCID lCid;
    CHARSETINFO cs;
    PKL pKl;

    /* Create keyboard layout object */
    pKl = UserCreateObject(gHandleTable, NULL, NULL, NULL, TYPE_KBDLAYOUT, sizeof(KL));
    if (!pKl)
    {
        ERR("Failed to create object!\n");
        return NULL;
    }

    pKl->hkl = hKL;
    pKl->spkf = UserLoadKbdFile(pwszKLID);

    /* Dereference keyboard layout */
    UserDereferenceObject(pKl);

    /* If we failed, remove KL object */
    if (!pKl->spkf)
    {
        ERR("UserLoadKbdFile(%wZ) failed!\n", pwszKLID);
        UserDeleteObject(pKl->head.h, TYPE_KBDLAYOUT);
        return NULL;
    }

    // Up to Language Identifiers..
    RtlUnicodeStringToInteger(pwszKLID, (ULONG)16, (PULONG)&lCid);
    TRACE("Language Identifiers %wZ LCID 0x%x\n", pwszKLID, lCid);
    if (co_IntGetCharsetInfo(lCid, &cs))
    {
       pKl->iBaseCharset = cs.ciCharset;
       pKl->dwFontSigs = cs.fs.fsCsb[0];
       pKl->CodePage = (USHORT)cs.ciACP;
       TRACE("Charset %u Font Sig %lu CodePage %u\n", pKl->iBaseCharset, pKl->dwFontSigs, pKl->CodePage);
    }
    else
    {
       pKl->iBaseCharset = ANSI_CHARSET;
       pKl->dwFontSigs = FS_LATIN1;
       pKl->CodePage = CP_ACP;
    }

    // Set initial system character set and font signature.
    if (gSystemFS == 0)
    {
       gSystemCPCharSet = pKl->iBaseCharset;
       gSystemFS = pKl->dwFontSigs;
    }

    return pKl;
}
Exemplo n.º 4
0
/* IntAttachMonitor
 *
 * Creates a new MONITOR and appends it to the list of monitors.
 *
 * Arguments
 *
 *   pGdiDevice     Pointer to the PDEVOBJ onto which the monitor was attached
 *   DisplayNumber  Display Number (starting with 0)
 *
 * Return value
 *   Returns a NTSTATUS
 */
NTSTATUS
IntAttachMonitor(IN PDEVOBJ *pGdiDevice,
                 IN ULONG DisplayNumber)
{
    PMONITOR Monitor;
    WCHAR Buffer[CCHDEVICENAME];

    TRACE("Attaching monitor...\n");

    /* create new monitor object */
    Monitor = IntCreateMonitorObject();
    if (Monitor == NULL)
    {
        TRACE("Couldnt create monitor object\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    _snwprintf(Buffer, CCHDEVICENAME, L"\\\\.\\DISPLAY%d", DisplayNumber + 1);
    if (!RtlCreateUnicodeString(&Monitor->DeviceName, Buffer))
    {
        TRACE("Couldn't duplicate monitor name!\n");
        UserDereferenceObject(Monitor);
        UserDeleteObject(UserHMGetHandle(Monitor), otMonitor);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    Monitor->GdiDevice = pGdiDevice;
    Monitor->cWndStack = 0;

    if (gMonitorList == NULL)
    {
        TRACE("Primary monitor is beeing attached\n");
        Monitor->IsPrimary = TRUE;
        gMonitorList = Monitor;
    }
    else
    {
        PMONITOR p;
        TRACE("Additional monitor is beeing attached\n");
        for (p = gMonitorList; p->Next != NULL; p = p->Next)
        {
            p->Next = Monitor;
        }
        Monitor->Prev = p;
    }

    IntUpdateMonitorSize(pGdiDevice);

    return STATUS_SUCCESS;
}
Exemplo n.º 5
0
/* IntDestroyMonitorObject
 *
 * Destroys a MONITOR
 * You have to be the owner of the monitors lock to safely destroy it.
 *
 * Arguments
 *
 *   pMonitor
 *      Pointer to the MONITOR which shall be deleted
 */
static
void
IntDestroyMonitorObject(IN PMONITOR pMonitor)
{
    /* Remove monitor region */
    if (pMonitor->hrgnMonitor)
    {
        GreSetObjectOwner(pMonitor->hrgnMonitor, GDI_OBJ_HMGR_POWNED);
        GreDeleteObject(pMonitor->hrgnMonitor);
    }

    /* Destroy monitor object */
    UserDereferenceObject(pMonitor);
    UserDeleteObject(UserHMGetHandle(pMonitor), TYPE_MONITOR);
}
Exemplo n.º 6
0
static VOID FASTCALL
IntFreeElementData(PCLIP pElement)
{
    if (!IS_DATA_DELAYED(pElement) &&
        !IS_DATA_SYNTHESIZED(pElement))
    {
        if (pElement->fGlobalHandle)
            UserDeleteObject(pElement->hData, TYPE_CLIPDATA);
        else if (pElement->fmt == CF_BITMAP || pElement->fmt == CF_PALETTE ||
                 pElement->fmt == CF_DSPBITMAP)
        {
            GreSetObjectOwner(pElement->hData, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(pElement->hData);
        }
    }
}
Exemplo n.º 7
0
static
BOOL
FASTCALL
IntRemoveEvent(PEVENTHOOK pEH)
{
   if (pEH)
   {
      TRACE("IntRemoveEvent pEH 0x%x\n",pEH);
      KeEnterCriticalRegion();
      RemoveEntryList(&pEH->Chain);
      GlobalEvents->Counts--;
      if (!GlobalEvents->Counts) gpsi->dwInstalledEventHooks = 0;
      UserDeleteObject(UserHMGetHandle(pEH), otEvent);
      KeLeaveCriticalRegion();
      return TRUE;
   }
   return FALSE;
}
Exemplo n.º 8
0
HANDLE APIENTRY
NtUserConvertMemHandle(
   PVOID pData,
   DWORD cbData)
{
    HANDLE hMem = NULL;
    PCLIPBOARDDATA pMemObj;

    UserEnterExclusive();

    /* Create Clipboard data object */
    pMemObj = UserCreateObject(gHandleTable, NULL, NULL, &hMem, TYPE_CLIPDATA, sizeof(CLIPBOARDDATA) + cbData);
    if (!pMemObj)
        goto cleanup;

    pMemObj->cbData = cbData;

    /* Copy data */
    _SEH2_TRY
    {
        ProbeForRead(pData, cbData, 1);
        memcpy(pMemObj->Data, pData, cbData);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        pMemObj = NULL;
    }
    _SEH2_END;

    /* Release the extra reference (UserCreateObject added 2 references) */
    UserDereferenceObject(pMemObj);

    /* If we failed to copy data, remove handle */
    if (!pMemObj)
    {
        UserDeleteObject(hMem, TYPE_CLIPDATA);
        hMem = NULL;
    }

cleanup:
    UserLeave();

    return hMem;
}
Exemplo n.º 9
0
/*
 * UnloadKbdFile
 *
 * Destroys specified Keyboard File object
 */
static
VOID
UnloadKbdFile(_In_ PKBDFILE pkf)
{
    PKBDFILE *ppkfLink = &gpkfList;
    NT_ASSERT(pkf != NULL);

    /* Find previous object */
    while (*ppkfLink)
    {
        if (*ppkfLink == pkf)
            break;

        ppkfLink = &(*ppkfLink)->pkfNext;
    }

    if (*ppkfLink == pkf)
        *ppkfLink = pkf->pkfNext;

    EngUnloadImage(pkf->hBase);
    UserDeleteObject(pkf->head.h, TYPE_KBDFILE);
}
Exemplo n.º 10
0
BOOLEAN
APIENTRY
NtUserDestroyAcceleratorTable(
    HACCEL hAccel)
{
    PACCELERATOR_TABLE Accel;
    DECLARE_RETURN(BOOLEAN);

    /* FIXME: If the handle table is from a call to LoadAcceleratorTable, decrement it's
       usage count (and return TRUE).
    FIXME: Destroy only tables created using CreateAcceleratorTable.
     */

    TRACE("NtUserDestroyAcceleratorTable(Table %p)\n", hAccel);
    UserEnterExclusive();

    if (!(Accel = UserGetAccelObject(hAccel)))
    {
        RETURN( FALSE);
    }

    if (Accel->Table != NULL)
    {
        ExFreePoolWithTag(Accel->Table, USERTAG_ACCEL);
        Accel->Table = NULL;
    }

    UserDeleteObject(hAccel, TYPE_ACCELTABLE);

    RETURN( TRUE);

CLEANUP:
    TRACE("Leave NtUserDestroyAcceleratorTable(Table %p) = %u\n", hAccel, _ret_);
    UserLeave();
    END_CLEANUP;
}
Exemplo n.º 11
0
HACCEL
APIENTRY
NtUserCreateAcceleratorTable(
    LPACCEL Entries,
    ULONG EntriesCount)
{
    PACCELERATOR_TABLE Accel;
    HACCEL hAccel;
    ULONG Index;
    NTSTATUS Status = STATUS_SUCCESS;
    DECLARE_RETURN(HACCEL);

    TRACE("Enter NtUserCreateAcceleratorTable(Entries %p, EntriesCount %u)\n",
          Entries, EntriesCount);
    UserEnterExclusive();

    if (!Entries || EntriesCount <= 0)
    {
        SetLastNtError(STATUS_INVALID_PARAMETER);
        RETURN( (HACCEL) NULL );
    }

    Accel = UserCreateObject(gHandleTable, NULL, NULL, (PHANDLE)&hAccel, TYPE_ACCELTABLE, sizeof(ACCELERATOR_TABLE));

    if (Accel == NULL)
    {
        SetLastNtError(STATUS_NO_MEMORY);
        RETURN( (HACCEL) NULL );
    }

    Accel->Count = EntriesCount;
    Accel->Table = ExAllocatePoolWithTag(PagedPool, EntriesCount * sizeof(ACCEL), USERTAG_ACCEL);
    if (Accel->Table == NULL)
    {
        UserDereferenceObject(Accel);
        UserDeleteObject(hAccel, TYPE_ACCELTABLE);
        SetLastNtError(STATUS_NO_MEMORY);
        RETURN( (HACCEL) NULL);
    }

    _SEH2_TRY
    {
        ProbeForRead(Entries, EntriesCount * sizeof(ACCEL), 4);

        for (Index = 0; Index < EntriesCount; Index++)
        {
            Accel->Table[Index].fVirt = Entries[Index].fVirt & FVIRT_MASK;
            if(Accel->Table[Index].fVirt & FVIRTKEY)
            {
                Accel->Table[Index].key = Entries[Index].key;
            }
            else
            {
                RtlMultiByteToUnicodeN(&Accel->Table[Index].key,
                sizeof(WCHAR),
                NULL,
                (PCSTR)&Entries[Index].key,
                sizeof(CHAR));
            }

            Accel->Table[Index].cmd = Entries[Index].cmd;
        }
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        Status = _SEH2_GetExceptionCode();
    }
    _SEH2_END;

    if (!NT_SUCCESS(Status))
    {
        ExFreePoolWithTag(Accel->Table, USERTAG_ACCEL);
        UserDereferenceObject(Accel);
        UserDeleteObject(hAccel, TYPE_ACCELTABLE);
        SetLastNtError(Status);
        RETURN( (HACCEL) NULL);
    }

    /* FIXME: Save HandleTable in a list somewhere so we can clean it up again */

    RETURN(hAccel);

CLEANUP:
    TRACE("Leave NtUserCreateAcceleratorTable(Entries %p, EntriesCount %u) = %p\n",
          Entries, EntriesCount, _ret_);
    UserLeave();
    END_CLEANUP;
}
Exemplo n.º 12
0
/*
 * @implemented
 */
DWORD_PTR
APIENTRY
NtUserCallOneParam(
   DWORD_PTR Param,
   DWORD Routine)
{
   DECLARE_RETURN(DWORD_PTR);

   TRACE("Enter NtUserCallOneParam\n");

   UserEnterExclusive();

   switch(Routine)
   {
      case ONEPARAM_ROUTINE_POSTQUITMESSAGE:
          {
                PTHREADINFO pti;
                pti = PsGetCurrentThreadWin32Thread();
                MsqPostQuitMessage(pti->MessageQueue, Param);
                RETURN(TRUE);
          }

      case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS:
         {
             PSMWP psmwp;
             HDWP hDwp = NULL;
             INT count = (INT)Param;

             if (count < 0)
             {
                EngSetLastError(ERROR_INVALID_PARAMETER);
                RETURN(0);
             }
             /* Windows allows zero count, in which case it allocates context for 8 moves */
             if (count == 0) count = 8;

             psmwp = (PSMWP) UserCreateObject( gHandleTable,
                                               NULL,
                                              (PHANDLE)&hDwp,
                                               otSMWP,
                                               sizeof(SMWP));
             if (!psmwp) RETURN(0);
             psmwp->acvr = ExAllocatePoolWithTag(PagedPool, count * sizeof(CVR), USERTAG_SWP);
             if (!psmwp->acvr)
             {
                UserDeleteObject(hDwp, otSMWP);
                RETURN(0);
             }
             RtlZeroMemory(psmwp->acvr, count * sizeof(CVR));
             psmwp->bHandle = TRUE;
             psmwp->ccvr = 0;          // actualCount
             psmwp->ccvrAlloc = count; // suggestedCount             
             RETURN((DWORD_PTR)hDwp);
         }

      case ONEPARAM_ROUTINE_SHOWCURSOR:
         RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) );

      case ONEPARAM_ROUTINE_GETDESKTOPMAPPING:
         {
             PTHREADINFO ti;
             ti = GetW32ThreadInfo();
             if (ti != NULL)
             {
                /* Try convert the pointer to a user mode pointer if the desktop is
                   mapped into the process */
                RETURN((DWORD_PTR)DesktopHeapAddressToUser((PVOID)Param));
             }
             else
             {
                RETURN(0);
             }
         }

      case ONEPARAM_ROUTINE_WINDOWFROMDC:
         RETURN( (DWORD_PTR)IntWindowFromDC((HDC)Param));

      case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
         {
            DWORD_PTR Result;

            Result = gspv.bMouseBtnSwap;
            gspv.bMouseBtnSwap = Param ? TRUE : FALSE;
            gpsi->aiSysMet[SM_SWAPBUTTON] = gspv.bMouseBtnSwap;
            RETURN(Result);
         }

      case ONEPARAM_ROUTINE_SWITCHCARETSHOWING:
         RETURN( (DWORD_PTR)IntSwitchCaretShowing((PVOID)Param));

      case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
         RETURN( (DWORD_PTR)IntSetCaretBlinkTime((UINT)Param));

      case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
         RETURN( (DWORD_PTR)MsqSetMessageExtraInfo((LPARAM)Param));

      case ONEPARAM_ROUTINE_CREATEEMPTYCUROBJECT:
         {
            PCURICON_OBJECT CurIcon;
			DWORD_PTR Result ;

            if (!(CurIcon = IntCreateCurIconHandle()))
            {
               EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
               RETURN(0);
            }

            Result = (DWORD_PTR)CurIcon->Self;
			UserDereferenceObject(CurIcon);
			RETURN(Result);
         }

      case ONEPARAM_ROUTINE_GETCURSORPOSITION:
         {
             BOOL ret = TRUE;

            _SEH2_TRY
            {
               ProbeForWrite((POINT*)Param,sizeof(POINT),1);
               RtlCopyMemory((POINT*)Param,&gpsi->ptCursor,sizeof(POINT));
            }
            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
            {
                SetLastNtError(_SEH2_GetExceptionCode());
                ret = FALSE;
            }
            _SEH2_END;

            RETURN (ret);
         }

      case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
         {
            BOOL Enable;
            PPROCESSINFO Process = PsGetCurrentProcessWin32Process();

            if(Process != NULL)
            {
               Enable = (BOOL)(Param != 0);

               if(Enable)
               {
                  Process->W32PF_flags &= ~W32PF_NOWINDOWGHOSTING;
               }
               else
               {
                  Process->W32PF_flags |= W32PF_NOWINDOWGHOSTING;
               }

               RETURN( TRUE);
            }

            RETURN( FALSE);
         }

      case ONEPARAM_ROUTINE_GETINPUTEVENT:
         RETURN( (DWORD_PTR)IntMsqSetWakeMask(Param));

      case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
         RETURN( UserGetKeyboardType(Param));

      case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT:
         RETURN( (DWORD_PTR)UserGetKeyboardLayout(Param));

      case ONEPARAM_ROUTINE_RELEASEDC:
         RETURN (UserReleaseDC(NULL, (HDC) Param, FALSE));

      case ONEPARAM_ROUTINE_REALIZEPALETTE:
         RETURN (UserRealizePalette((HDC) Param));

      case ONEPARAM_ROUTINE_GETQUEUESTATUS:
      {
         RETURN (IntGetQueueStatus((DWORD)Param));
      }
      case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
         /* FIXME: Should use UserEnterShared */
         RETURN(IntEnumClipboardFormats(Param));

      case ONEPARAM_ROUTINE_CSRSS_GUICHECK:
          IntUserManualGuiCheck(Param);
          RETURN(TRUE);

      case ONEPARAM_ROUTINE_GETCURSORPOS:
      {
          BOOL Ret = TRUE;
          PPOINTL pptl;
          PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
          if (pti->hdesk != InputDesktopHandle) RETURN(FALSE);
          _SEH2_TRY
          {
             pptl = (PPOINTL)Param;
             *pptl = gpsi->ptCursor;
          }
          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
          {
             Ret = FALSE;
          }
          _SEH2_END;
          RETURN(Ret);
      }
      case ONEPARAM_ROUTINE_SETPROCDEFLAYOUT:
      {
          PPROCESSINFO ppi;
          if (Param & LAYOUT_ORIENTATIONMASK)
          {
             ppi = PsGetCurrentProcessWin32Process();
             ppi->dwLayout = Param;
             RETURN(TRUE);
          }
          EngSetLastError(ERROR_INVALID_PARAMETER);
          RETURN(FALSE);
      }
      case ONEPARAM_ROUTINE_GETPROCDEFLAYOUT:
      {
          BOOL Ret = TRUE;
          PPROCESSINFO ppi;
          PDWORD pdwLayout;
          if ( PsGetCurrentProcess() == CsrProcess)
          {
             EngSetLastError(ERROR_INVALID_ACCESS);
             RETURN(FALSE);
          }
          ppi = PsGetCurrentProcessWin32Process();
          _SEH2_TRY
          {
             pdwLayout = (PDWORD)Param;
             *pdwLayout = ppi->dwLayout;
          }
          _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
          {
             SetLastNtError(_SEH2_GetExceptionCode());
             Ret = FALSE;
          }
          _SEH2_END;
          RETURN(Ret);
      }
      case ONEPARAM_ROUTINE_REPLYMESSAGE:
          RETURN (co_MsqReplyMessage((LRESULT) Param));
      case ONEPARAM_ROUTINE_MESSAGEBEEP:
          RETURN ( UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, Param) );
		  /* TODO: Implement sound sentry */
   }
   ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
           Routine, Param);
   EngSetLastError(ERROR_INVALID_PARAMETER);
   RETURN( 0);

CLEANUP:
   TRACE("Leave NtUserCallOneParam, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}
Exemplo n.º 13
0
/*
 * UserLoadKbdFile
 *
 * Loads keyboard layout DLL and creates KBDFILE object
 */
static PKBDFILE
UserLoadKbdFile(PUNICODE_STRING pwszKLID)
{
    PKBDFILE pkf, pRet = NULL;
    NTSTATUS Status;
    ULONG cbSize;
    HKEY hKey = NULL;
    WCHAR wszLayoutPath[MAX_PATH] = L"\\SystemRoot\\System32\\";
    WCHAR wszLayoutRegKey[256] = L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet\\"
                                 L"Control\\Keyboard Layouts\\";

    /* Create keyboard layout file object */
    pkf = UserCreateObject(gHandleTable, NULL, NULL, NULL, TYPE_KBDFILE, sizeof(KBDFILE));
    if (!pkf)
    {
        ERR("Failed to create object!\n");
        return NULL;
    }

    /* Set keyboard layout name */
    swprintf(pkf->awchKF, L"%wZ", pwszKLID);

    /* Open layout registry key */
    RtlStringCbCatW(wszLayoutRegKey, sizeof(wszLayoutRegKey), pkf->awchKF);
    Status = RegOpenKey(wszLayoutRegKey, &hKey);
    if (!NT_SUCCESS(Status))
    {
        ERR("Failed to open keyboard layouts registry key %ws (%lx)\n", wszLayoutRegKey, Status);
        goto cleanup;
    }

    /* Read filename of layout DLL */
    cbSize = sizeof(wszLayoutPath) - wcslen(wszLayoutPath)*sizeof(WCHAR);
    Status = RegQueryValue(hKey,
                           L"Layout File",
                           REG_SZ,
                           wszLayoutPath + wcslen(wszLayoutPath),
                           &cbSize);

    if (!NT_SUCCESS(Status))
    {
        ERR("Can't get layout filename for %wZ (%lx)\n", pwszKLID, Status);
        goto cleanup;
    }

    /* Load keyboard file now */
    if (!UserLoadKbdDll(wszLayoutPath, &pkf->hBase, &pkf->pKbdTbl))
    {
        ERR("Failed to load %ws dll!\n", wszLayoutPath);
        goto cleanup;
    }

    /* Update next field */
    pkf->pkfNext = gpkfList;
    gpkfList = pkf;

    /* Return keyboard file */
    pRet = pkf;

cleanup:
    if (hKey)
        ZwClose(hKey);
    if (pkf)
        UserDereferenceObject(pkf); // we dont need ptr anymore
    if (!pRet)
    {
        /* We have failed - destroy created object */
        if (pkf)
            UserDeleteObject(pkf->head.h, TYPE_KBDFILE);
    }

    return pRet;
}
Exemplo n.º 14
0
BOOLEAN FASTCALL
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOLEAN bForce)
{
    if(CurIcon->CURSORF_flags & CURSORF_CURRENT)
    {
        /* Mark the object as destroyed, and fail, as per tests */
        TRACE("Cursor is current, marking as destroyed.\n");
        UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
        return FALSE;
    }

    if(CurIcon->head.ppi != PsGetCurrentProcessWin32Process())
    {
        /* This object doesn't belong to the current process */
        WARN("Trying to delete foreign cursor!\n");
        UserDereferenceObject(CurIcon);
        EngSetLastError(ERROR_DESTROY_OBJECT_OF_OTHER_THREAD);
        return FALSE;
    }
    
    /* Do not destroy it if it is shared. (And we're not forced to) */
    if((CurIcon->CURSORF_flags & CURSORF_LRSHARED) && !bForce)
    {
        /* Tests show this is a valid call */
        WARN("Trying to destroy shared cursor!\n");
        UserDereferenceObject(CurIcon);
        return TRUE;
    }

    if(!(CurIcon->CURSORF_flags & CURSORF_ACON))
    {
        HBITMAP bmpMask = CurIcon->hbmMask;
        HBITMAP bmpColor = CurIcon->hbmColor;
        HBITMAP bmpAlpha = CurIcon->hbmAlpha;

        /* Delete bitmaps */
        if (bmpMask)
        {
            GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(bmpMask);
            CurIcon->hbmMask = NULL;
        }
        if (bmpColor)
        {
            GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(bmpColor);
            CurIcon->hbmColor = NULL;
        }
        if (bmpAlpha)
        {
            GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
            GreDeleteObject(bmpAlpha);
            CurIcon->hbmAlpha = NULL;
        }
    }
    else
    {
        PACON AniCurIcon = (PACON)CurIcon;
        UINT i;

        for(i = 0; i < AniCurIcon->cpcur; i++)
            IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE);
        ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR);
    }

    if (CurIcon->CURSORF_flags & CURSORF_LRSHARED)
    {
        if (!IS_INTRESOURCE(CurIcon->strName.Buffer))
            ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
        if (CurIcon->atomModName)
            RtlDeleteAtomFromAtomTable(gAtomTable, CurIcon->atomModName);
        CurIcon->strName.Buffer = NULL;
        CurIcon->atomModName = 0;
    }

    /* We were given a pointer, no need to keep the reference any longer! */
    UserDereferenceObject(CurIcon);
    return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
}