DLL Call - _WIM_GetMountedImageCount und _WIM_GetMountedImages

  • Hi Leute,
    ich bekomme einfach folgende Funktion nicht aufgerufen:

    Code
    BOOL
    WINAPI
    WIMGetMountedImages(
        PWIM_MOUNT_LIST pMountList,
        PDWORD          pcbMountListLength
        );

    Hier der Link zur Funktion und dessen Parameter:
    hier

    Die DLL die verwendet wird ist wimgapi.dll

    Die Funktion soll prüfen, welche Images "gemounted" sind. Leider macht es keinen Sinn die DLL anzubieten, da man erstmal ein Image mounten muss um überhaupt einen Return zu bekommen und das ist mit etwas Aufwand verbunden.

    Folgendes habe ich versucht:

    [autoit]


    Global Const $tagWIM_MOUNT_LIST = "WCHAR WimPath[260];WCHAR MountPath[260];DWORD ImageIndex;BOOL MountedForRW"

    [/autoit][autoit][/autoit][autoit]

    ; #STRUCTURE# ===================================================================================================================
    ; Name...........: $tagWIM_MOUNT_INFO_LEVEL1
    ; Description ...: Contains information retrieved by the _WIM_GetMountedImageList function.
    ; Fields ........: WimPath - Specifies the full path to the .wim file.
    ; MountPath - Specifies the full path to the directory where the image is mounted.
    ; ImageIndex - Specifies the image index within the .wim file specified in WimPath.
    ; MountFlags - Specifies the current state of the mount point.
    ; | $WIM_MOUNT_FLAG_MOUNTED - The image is actively mounted.
    ; | $WIM_MOUNT_FLAG_MOUNTING - The image is in the process of mounting.
    ; | $WIM_MOUNT_FLAG_REMOUNTABLE - The image is not mounted, but is capable of being remounted.
    ; | $WIM_MOUNT_FLAG_INVALID - The image mount point is no longer valid.
    ; | $WIM_MOUNT_FLAG_NO_WIM - TThe WIM file backing the mount point is missing or inaccessible.
    ; | $WIM_MOUNT_FLAG_NO_MOUNTDIR - The image mount point has been removed or replaced.
    ; | $WIM_MOUNT_FLAG_MOUNTDIR_REPLACED - The mount point has been replaced with by a different mounted image.
    ; | $WIM_MOUNT_FLAG_READWRITE - The image has been mounted with read-write access.
    ; Author ........: Jonathan Holmgren (Homes32)
    ; Remarks .......:
    ; ===============================================================================================================================

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    _Test()
    Func _Test()

    [/autoit][autoit][/autoit][autoit]

    Local $a[2] = [DllStructCreate($tagWIM_MOUNT_LIST),DllStructCreate($tagWIM_MOUNT_LIST)]

    [/autoit][autoit][/autoit][autoit]

    Local $aReturn1[10] ; array to hold the return data
    Local $pWimInfo1 = DllStructCreate($tagWIM_MOUNT_LIST)
    Local $test = DllStructGetSize($a)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;~ MsgBox(0, "safdad", $test)

    [/autoit][autoit][/autoit][autoit]

    ;~ $aResult = DllCall($ghwimgapi, "bool", "WIMGetMountedImages", _
    ;~ "ptr", DllStructGetPtr($pWimInfo1), _
    ;~ "dword", DllStructGetSize($pWimInfo1))
    ;~ If @error Then Return SetError(@error, @extended, 0)

    [/autoit][autoit][/autoit][autoit]

    $aResult = DllCall($ghwimgapi, "bool", "WIMGetMountedImages", _
    "ptr", DllStructGetPtr($a), _
    "ptr", DllStructGetPtr($test))

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $aResult1 = DllCall($ghwimgapi, "bool", "WIMGetMountedImages", _
    "ptr", DllStructGetPtr($pWimInfo1), _
    "ptr", DllStructGetPtr($test))
    ;~ If @error Then
    ;~ MsgBox(0, "safdad", @error & " " & @extended)
    _ArrayDisplay($aResult)
    _ArrayDisplay($aResult1)
    MsgBox(0, "safdad", $aResult & " " & $aResult1)

    ;~ Return $aResult
    ;~ Return SetError(@error, @extended, 0)
    ;~ EndIf

    [/autoit][autoit][/autoit][autoit]

    EndFunc

    [/autoit]

    Hat jemand eine Idee wie ich das zum laufen bekomme??

    Danke schonmal!

    3 Mal editiert, zuletzt von Trolleule1337 (5. Februar 2013 um 04:07)

  • Ich kann's nicht testen, aber so irgendwie vielleicht:

    Spoiler anzeigen
    [autoit]

    Global Const $tagWIM_MOUNT_LIST = "WCHAR WimPath[260];WCHAR MountPath[260];DWORD ImageIndex;BOOL MountedForRW"

    [/autoit] [autoit][/autoit] [autoit]

    Global $tWIM_MOUNT_LIST = DllStructCreate($tagWIM_MOUNT_LIST & ";" & $tagWIM_MOUNT_LIST)
    Global $pWIM_MOUNT_LIST = DllStructGetPtr($tWIM_MOUNT_LIST)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $aResult = DllCall("wimgapi.dll", "bool", "WIMGetMountedImages", "ptr", $pWIM_MOUNT_LIST, "ptr", 0)

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite("Return value: " & $aResult[0] & @CRLF)
    ConsoleWrite("Bytes received: " & $aResult[2] & @CRLF)

    [/autoit]
  • danke, ich hab nochmal bisschen mit den parametern gespielt, aber bekomme nur 0 als return, allerdings auch bytes:

    Zitat

    Return value: 0
    Bytes received: 0x03D1F580

    Aktuell ist ein image gemounted, also müsste eine Ausgabe möglich sein. Allerdings ist die Funktion veraltet und wurde von dieser ersetzt.
    Die finde ich aber noch schwerer ?(

  • ok habe "ptr" mit "dword*" ersetzt.

    Zitat

    Und wahrscheinlich wirst du mehr als nur zwei Strukturen brauchen. Deswegen kommt wahrscheinlich auch die 0 zurück.

    Wie mache ich das jetzt?

    [autoit]

    Local $tWIM_MOUNT_LIST = DllStructCreate($tagWIM_MOUNT_LIST & ";" & $tagWIM_MOUNT_LIST)

    [/autoit]

    also egal wie viele & ";" & $tagWIM_MOUNT_LIST ich noch dran hänge, es ändert nur was am hex wert.

    Output:

    Zitat

    Return value: 0
    $aResult[1]: 0x03BFF580
    Bytes received: 1048

  • ja klappt denke ich, bekomme zurück:

    Zitat

    Return value: 1
    $aResult[1]: 0x03B9F628
    Bytes received: 1048

    Hmm, müsste ich nicht auch noch die Daten aus dem struct zurück bekommen, also WimPath, MountPath, ImageIndex undMountedForRW??

    Danke!

  • yeah funkey... du bist funky. Läuft!

    Ich hab nun 2 images "gemountet", damit das klappt, brauchen wir die zeile:

    Zitat

    Local $tWIM_MOUNT_LIST = DllStructCreate($tagWIM_MOUNT_LIST & ";" & $tagWIM_MOUNT_LIST)

    sonst klappt es nicht. Die Daten des ersten images rufe ich so ab:

    [autoit]


    Local $tWIM_MOUNT_LIST = DllStructCreate($tagWIM_MOUNT_LIST & ";" & $tagWIM_MOUNT_LIST)
    Local $pWIM_MOUNT_LIST = DllStructGetPtr($tWIM_MOUNT_LIST)

    [/autoit][autoit][/autoit][autoit]

    $aResult = DllCall("wimgapi.dll", "bool", "WIMGetMountedImages", "ptr", $pWIM_MOUNT_LIST, "dword*", DllStructGetSize($tWIM_MOUNT_LIST))

    $aReturn[1] = DllStructGetData($tWIM_MOUNT_LIST, "WimPath")
    $aReturn[2] = DllStructGetData($tWIM_MOUNT_LIST, "MountPath")
    $aReturn[3] = DllStructGetData($tWIM_MOUNT_LIST, "ImageIndex")
    $aReturn[4] = DllStructGetData($tWIM_MOUNT_LIST, "MountedForRW")

    [/autoit]

    Aber wie die des 2ten???

    Danke jung :thumbup:

    Einmal editiert, zuletzt von Trolleule1337 (28. Januar 2013 um 18:16)

  • Viele Wege führen nach Rom ... ;)

    Variante 1:

    Spoiler anzeigen
    [autoit]

    Global Const $tagWIM_MOUNT_LIST = "WCHAR WimPath[260];WCHAR MountPath[260];DWORD ImageIndex;BOOL MountedForRW;"

    [/autoit] [autoit][/autoit] [autoit]

    Func Test ( )

    Local $wml = DllStructCreate ($tagWIM_MOUNT_LIST&$tagWIM_MOUNT_LIST)
    Local $dwLength = DllStructCreate ("DWORD")
    Local $bResult

    $bResult = WIMGetMountedImages (DllStructGetPtr ($wml), DllStructGetPtr ($dwLength))

    ConsoleWrite (StringFormat ("WIMGetMountedImages gibt %d zurück.\n", $bResult))
    ConsoleWrite (StringFormat ("Anzahl Bytes erhalten: %d\n", DllStructGetData ($dwLength, 1)))

    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func WIMGetMountedImages ($pMountList, $pcbMountListLength)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aRes = DllCall ("wimgapi.dll", "BOOL", "WIMGetMountedImages", _
    "PTR", $pMountList, _
    "PTR", $pcbMountListLength)
    Return $aRes[0]

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit]

    Variante 2:

    Spoiler anzeigen
    [autoit]

    Global Const $tagWIM_MOUNT_LIST = "WCHAR WimPath[260];WCHAR MountPath[260];DWORD ImageIndex;BOOL MountedForRW;"

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func Test ( )

    Local $wml = DllStructCreate ($tagWIM_MOUNT_LIST&$tagWIM_MOUNT_LIST)
    Local $dwLength
    Local $bResult

    $bResult = WIMGetMountedImages (DllStructGetPtr ($wml), $dwLength)

    ConsoleWrite (StringFormat ("WIMGetMountedImages gibt %d zurück.\n", $bResult))
    ConsoleWrite (StringFormat ("Anzahl Bytes erhalten: %d\n", $dwLength))

    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func WIMGetMountedImages ($pMountList, ByRef $pcbMountListLength)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aRes = DllCall ("wimgapi.dll", "BOOL", "WIMGetMountedImages", _
    "PTR", $pMountList, _
    "DWORD*", 0)
    $pcbMountListLength = $aRes[2]
    Return $aRes[0]

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit]

    Grüße
    Greenhorn


  • Danke für die Mühe jung, leider geben beiden Varianten 0 zurück. Habe jetzt nicht nachgesehen warum, da funkys Lösung funktioniert.

    ich muss nur noch wissen wie ich das Array of Struct auslese? ?(

    Zitat

    Local $tWIM_MOUNT_LIST = DllStructCreate($tagWIM_MOUNT_LIST & ";" & $tagWIM_MOUNT_LIST)

    Deine Variante:

    Zitat

    Local $tWIM_MOUNT_LIST = DllStructCreate($tagWIM_MOUNT_LIST & $tagWIM_MOUNT_LIST)

    [autoit]

    $aReturn[1] = DllStructGetData($tWIM_MOUNT_LIST, "WimPath")
    $aReturn[2] = DllStructGetData($tWIM_MOUNT_LIST, "MountPath")
    $aReturn[3] = DllStructGetData($tWIM_MOUNT_LIST, "ImageIndex")
    $aReturn[4] = DllStructGetData($tWIM_MOUNT_LIST, "MountedForRW")

    [/autoit]
  • Ich habe doch gesagt, dass du mit dem Index arbeiten musst.

    Spoiler anzeigen
    [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Erste Struktur
    $aReturn[1] = DllStructGetData($tWIM_MOUNT_LIST, 1) ;"WimPath"
    $aReturn[2] = DllStructGetData($tWIM_MOUNT_LIST, 2) ;"MountPath"
    $aReturn[3] = DllStructGetData($tWIM_MOUNT_LIST, 3) ;"ImageIndex"
    $aReturn[4] = DllStructGetData($tWIM_MOUNT_LIST, 4) ;"MountedForRW"

    [/autoit] [autoit][/autoit] [autoit]

    ;Zweite Struktur
    $aReturn[5] = DllStructGetData($tWIM_MOUNT_LIST, 5) ;"WimPath"
    $aReturn[6] = DllStructGetData($tWIM_MOUNT_LIST, 6) ;"MountPath"
    $aReturn[7] = DllStructGetData($tWIM_MOUNT_LIST, 7) ;"ImageIndex"
    $aReturn[8] = DllStructGetData($tWIM_MOUNT_LIST, 8) ;"MountedForRW"

    [/autoit]
  • So hab das Ganze mal aufgeräumt und den Return aufbereitet, sodass ich die Informationen in einem Listview darstellen kann.

    Hier der Code für die UDF:

    [autoit]

    Func _WIM_GetMountedImages()

    [/autoit][autoit][/autoit][autoit]

    Local $WIM_MOUNT_LIST[3]
    Local $tWIM_MOUNT_LIST = DllStructCreate($tagWIM_MOUNT_LIST & ";" & $tagWIM_MOUNT_LIST) ; reserved for two images
    Local $pWIM_MOUNT_LIST = DllStructGetPtr($tWIM_MOUNT_LIST)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $aResult = DllCall("wimgapi.dll", "bool", "WIMGetMountedImages", _
    "ptr", $pWIM_MOUNT_LIST, _
    "dword*", DllStructGetSize($tWIM_MOUNT_LIST) _
    )
    If @error Then Return SetError(@error, @extended, 0)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ; first structure
    For $i = 1 To 4
    $WIM_MOUNT_LIST[1] &= DllStructGetData($tWIM_MOUNT_LIST, $i)
    If $i = 4 Then ExitLoop
    $WIM_MOUNT_LIST[1] &= "|"
    Next

    [/autoit][autoit][/autoit][autoit]

    If $aResult[2] = 1048 Then
    $pdwImageCount = 1
    $WIM_MOUNT_LIST[0] = $pdwImageCount
    ReDim $WIM_MOUNT_LIST[$pdwImageCount+1]
    Return $WIM_MOUNT_LIST
    Else
    $pdwImageCount = 2
    $WIM_MOUNT_LIST[0] = $pdwImageCount
    ReDim $WIM_MOUNT_LIST[$pdwImageCount+1]
    EndIf

    [/autoit][autoit][/autoit][autoit]

    ; second structure
    For $i = 5 To 8
    $WIM_MOUNT_LIST[2] &= DllStructGetData($tWIM_MOUNT_LIST, $i)
    If $i = 8 Then ExitLoop
    $WIM_MOUNT_LIST[2] &= "|"
    Next

    [/autoit][autoit][/autoit][autoit]

    Return $WIM_MOUNT_LIST
    EndFunc

    [/autoit]

    Hier der Code meines Projekts:

    [autoit]

    Func GetMountedImages()
    $WimMountList = _WIM_GetMountedImages()

    [/autoit][autoit][/autoit][autoit]

    For $i = 1 To $WimMountList[0]
    $MountInfo = StringSplit($WimMountList[$i], "|", 3)
    $MountedForRW = "R/W"
    If $MountInfo[3] = 0 Then $MountedForRW = "R"
    _GUICtrlListView_AddItem($umListView, $MountedForRW, $i-1)
    _GUICtrlListView_AddSubItem($umListView, $i-1, $MountInfo[1], 1, 1)
    _GUICtrlListView_AddSubItem($umListView, $i-1, $MountInfo[0], 2, 2)
    _GUICtrlListView_AddSubItem($umListView, $i-1, $MountInfo[2], 3, 3)
    Next

    [/autoit][autoit][/autoit][autoit]

    ; autosize column header
    _GUICtrlListView_SetColumnWidth($umListView, 0, $LVSCW_AUTOSIZE_USEHEADER)
    _GUICtrlListView_SetColumnWidth($umListView, 1, $LVSCW_AUTOSIZE_USEHEADER)
    _GUICtrlListView_SetColumnWidth($umListView, 2, $LVSCW_AUTOSIZE_USEHEADER)
    _GUICtrlListView_SetColumnWidth($umListView, 3, $LVSCW_AUTOSIZE_USEHEADER)

    [/autoit][autoit][/autoit][autoit]

    EndFunc

    [/autoit]

    Leider bin ich nicht zu 100% zufrieden, die Art wie ich es umgesetzt habe fühlt sich unsauber und unflexibel an. Was meint ihr?

    Danke an Alle!

  • Es gibt ja _WIM_GetImageCount, damit kannst du bestimmt über eine Schleife die benötigte Anzahl von Strukturen zusammenfügen und dann auch wieder über eine Schleife alle Werte daraus auslesen. Sollte kein Problem sein. Du kannst vielleicht auch gleich ein 2D-Array zurückgeben.

  • _WIM_GetImageCount gibt nur die Anzahl der im wim enthaltenen Images zurück. Die Funktion hat nichts mit mounted Images zu tun. An ein 2D Array hab ich auch gedacht. Glaubst du das ist besser oder so lassen?

  • ok sieht schon besser aus, was sagst du dazu?

    UDF code:

    [autoit]

    Func _WIM_GetMountedImages()

    [/autoit][autoit][/autoit][autoit]

    Local $WIM_MOUNT_LIST[1][4] ; ReDim later
    Local $tWIM_MOUNT_LIST = DllStructCreate($tagWIM_MOUNT_LIST & ";" & $tagWIM_MOUNT_LIST) ; reserved for two images
    Local $pWIM_MOUNT_LIST = DllStructGetPtr($tWIM_MOUNT_LIST)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $aResult = DllCall("wimgapi.dll", "bool", "WIMGetMountedImages", _
    "ptr", $pWIM_MOUNT_LIST, _
    "dword*", DllStructGetSize($tWIM_MOUNT_LIST) _
    )
    If @error Then Return SetError(@error, @extended, 0)

    [/autoit][autoit][/autoit][autoit]

    ; define mount count
    If $aResult[2] = 0 Then Return 0 ; no image mounted
    If $aResult[2] = 1048 Then $pdwImageCount = 1
    If $aResult[2] = 2096 Then $pdwImageCount = 2

    [/autoit][autoit][/autoit][autoit]

    ReDim $WIM_MOUNT_LIST[$pdwImageCount][4]

    [/autoit][autoit][/autoit][autoit]

    $k = 0 ; cell
    For $i = 1 To $pdwImageCount ; row
    For $j = 1 To Ubound($WIM_MOUNT_LIST, 2) ; column
    $k += 1
    $WIM_MOUNT_LIST[$i-1][$j-1] &= DllStructGetData($tWIM_MOUNT_LIST, $k)
    Next
    Next

    [/autoit][autoit][/autoit][autoit]

    Return $WIM_MOUNT_LIST
    EndFunc

    [/autoit]

    Projekt code:

    [autoit]

    Func GetMountedImages(ByRef $controlID)
    $WimMountList = _WIM_GetMountedImages()
    If $WimMountList = 0 Then Return

    [/autoit][autoit][/autoit][autoit]

    For $i = 1 To Ubound($WimMountList, 1)
    $MountedForRW = "R/W"
    If $WimMountList[$i-1][3] = 0 Then $MountedForRW = "R"
    _GUICtrlListView_AddItem($controlID, $MountedForRW, $i-1)
    _GUICtrlListView_AddSubItem($controlID, $i-1, $WimMountList[$i-1][1], 1, 1)
    _GUICtrlListView_AddSubItem($controlID, $i-1, $WimMountList[$i-1][0], 2, 2)
    _GUICtrlListView_AddSubItem($controlID, $i-1, $WimMountList[$i-1][2], 3, 3)
    Next

    [/autoit][autoit][/autoit][autoit]

    ; autosize column header
    _GUICtrlListView_SetColumnWidth($controlID, 0, $LVSCW_AUTOSIZE_USEHEADER)
    _GUICtrlListView_SetColumnWidth($controlID, 1, $LVSCW_AUTOSIZE_USEHEADER)
    _GUICtrlListView_SetColumnWidth($controlID, 2, $LVSCW_AUTOSIZE_USEHEADER)
    _GUICtrlListView_SetColumnWidth($controlID, 3, $LVSCW_AUTOSIZE_USEHEADER)

    [/autoit][autoit][/autoit][autoit]

    EndFunc

    [/autoit]

    Einmal editiert, zuletzt von Trolleule1337 (29. Januar 2013 um 15:11)

  • Besser, mir gefällt nur das Redim nicht und dass man vorher nicht weiß wieviele Images gemountet sind.
    Vielleicht kamm man das mit einem Extra-Aufruf der Funktion herausfinden?

    [autoit]

    Global $aResult = DllCall("wimgapi.dll", "bool", "WIMGetMountedImages", "ptr", 0, "dword*", 0)
    ConsoleWrite($aResult[2] & @CRLF)

    [/autoit]


    Was kommt dabei heraus? Irgendwie muss man ja herausfinden, wieviel Speicher man bereitstellen muss!