Changeset 14852 in vbox
- Timestamp:
- Dec 1, 2008 11:46:18 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/VBoxHDD-new.h
r14816 r14852 1049 1049 { 1050 1050 /** Name of the backend. */ 1051 c har *pszBackend;1051 const char *pszBackend; 1052 1052 /** Capabilities of the backend (a combination of the VD_CAP_* flags). */ 1053 1053 uint64_t uBackendCaps; … … 1072 1072 typedef VBOXHDD *PVBOXHDD; 1073 1073 1074 /** 1075 * Initializes HDD backends. 1076 * 1077 * @returns VBox status code. 1078 */ 1079 VBOXDDU_DECL(int) VDInit(); 1080 1081 /** 1082 * Destroys loaded HDD backends. 1083 * 1084 * @returns VBox status code. 1085 */ 1086 VBOXDDU_DECL(int) VDShutdown(); 1074 1087 1075 1088 /** -
trunk/src/VBox/Devices/Storage/RawHDDCore.cpp
r13580 r14852 1090 1090 /* paConfigInfo */ 1091 1091 NULL, 1092 /* hPlugin */ 1093 NIL_RTLDRMOD, 1092 1094 /* pfnCheckIfValid */ 1093 1095 rawCheckIfValid, -
trunk/src/VBox/Devices/Storage/VBoxHDD-new.cpp
r14350 r14852 67 67 unsigned uOpenFlags; 68 68 69 /** Handle for the shared object / DLL. */70 RTLDRMOD hPlugin;71 69 /** Function pointers for the various backend methods. */ 72 70 PCVBOXHDDBACKEND Backend; … … 129 127 #endif 130 128 131 static PCVBOXHDDBACKEND aBackends[] = 129 static unsigned g_cBackends = 0; 130 static PVBOXHDDBACKEND *g_apBackends = NULL; 131 static PVBOXHDDBACKEND aStaticBackends[] = 132 132 { 133 133 &g_RawBackend, 134 134 &g_VmdkBackend, 135 135 &g_VDIBackend, 136 &g_VhdBackend ,136 &g_VhdBackend 137 137 #ifdef VBOX_WITH_ISCSI 138 &g_ISCSIBackend,138 ,&g_ISCSIBackend 139 139 #endif 140 NULL141 140 }; 142 141 142 /** 143 * internal: add several backends. 144 */ 145 static int vdAddBackends(PVBOXHDDBACKEND *ppBackends, unsigned cBackends) 146 { 147 PVBOXHDDBACKEND *pTmp = (PVBOXHDDBACKEND*)RTMemRealloc(g_apBackends, 148 (g_cBackends + cBackends) * sizeof(PVBOXHDDBACKEND)); 149 if (RT_UNLIKELY(!pTmp)) 150 return VERR_NO_MEMORY; 151 g_apBackends = pTmp; 152 memcpy(&g_apBackends[g_cBackends], ppBackends, cBackends * sizeof(PVBOXHDDBACKEND)); 153 g_cBackends += cBackends; 154 return VINF_SUCCESS; 155 } 156 157 /** 158 * internal: add single backend. 159 */ 160 DECLINLINE(int) vdAddBackend(PVBOXHDDBACKEND pBackend) 161 { 162 return vdAddBackends(&pBackend, 1); 163 } 143 164 144 165 /** … … 159 180 * internal: find image format backend. 160 181 */ 161 static int vdFindBackend(const char *pszBackend, PCVBOXHDDBACKEND *ppBackend, 162 RTLDRMOD *phPlugin) 182 static int vdFindBackend(const char *pszBackend, PCVBOXHDDBACKEND *ppBackend) 163 183 { 164 184 int rc = VINF_SUCCESS; 165 185 PCVBOXHDDBACKEND pBackend = NULL; 166 RTLDRMOD hPlugin = NIL_RTLDRMOD; 167 168 for (unsigned i = 0; aBackends[i] != NULL; i++) 169 { 170 if (!strcmp(pszBackend, aBackends[i]->pszBackendName)) 171 { 172 pBackend = aBackends[i]; 186 187 if (!g_apBackends) 188 VDInit(); 189 190 for (unsigned i = 0; i < g_cBackends; i++) 191 { 192 if (!strcmp(pszBackend, g_apBackends[i]->pszBackendName)) 193 { 194 pBackend = g_apBackends[i]; 173 195 break; 174 196 } 175 197 } 176 177 /* If no static backend is found try loading a shared module with178 * pszBackend as filename. */179 if (!pBackend)180 {181 char szSharedLibPath[RTPATH_MAX];182 char *pszPluginName;183 184 rc = RTPathAppPrivateArch(szSharedLibPath, sizeof(szSharedLibPath));185 if (RT_FAILURE(rc))186 return rc;187 188 /* HDD Format Plugins have VBoxHDD as prefix, prepend it. */189 RTStrAPrintf(&pszPluginName, "%s/%s%s",190 szSharedLibPath, VBOX_HDDFORMAT_PLUGIN_PREFIX, pszBackend);191 if (!pszPluginName)192 {193 rc = VERR_NO_MEMORY;194 goto out;195 }196 197 /* Try to load the plugin (RTLdrLoad takes care of the suffix). */198 rc = SUPR3HardenedLdrLoad(pszPluginName, &hPlugin);199 if (RT_SUCCESS(rc))200 {201 PFNVBOXHDDFORMATLOAD pfnHDDFormatLoad;202 203 rc = RTLdrGetSymbol(hPlugin, VBOX_HDDFORMAT_LOAD_NAME,204 (void**)&pfnHDDFormatLoad);205 if (RT_FAILURE(rc) || !pfnHDDFormatLoad)206 {207 LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnHDDFormat=%#p\n", VBOX_HDDFORMAT_LOAD_NAME, pszPluginName, rc, pfnHDDFormatLoad));208 if (RT_SUCCESS(rc))209 rc = VERR_SYMBOL_NOT_FOUND;210 goto out;211 }212 213 /* Get the function table. */214 PVBOXHDDBACKEND pBE;215 rc = pfnHDDFormatLoad(&pBE);216 if (RT_FAILURE(rc))217 goto out;218 /* Check if the sizes match. If not this plugin is too old. */219 if (pBE->cbSize != sizeof(VBOXHDDBACKEND))220 {221 rc = VERR_VDI_UNSUPPORTED_VERSION;222 goto out;223 }224 pBackend = pBE;225 }226 else227 {228 /* If the backend plugin doesn't exist, don't treat this as an229 * error. Just return the NULL pointers. */230 rc = VINF_SUCCESS;231 }232 233 RTStrFree(pszPluginName);234 }235 236 out:237 if (RT_FAILURE(rc))238 {239 if (hPlugin != NIL_RTLDRMOD)240 RTLdrClose(hPlugin);241 hPlugin = NIL_RTLDRMOD;242 pBackend = NULL;243 }244 245 198 *ppBackend = pBackend; 246 *phPlugin = hPlugin;247 199 return rc; 248 200 } … … 614 566 615 567 /** 568 * internal: scans plugin directory and loads the backends have been found. 569 */ 570 static int vdLoadDynamicBackends() 571 { 572 int rc = VINF_SUCCESS; 573 PRTDIR pPluginDir = NULL; 574 575 /* Enumerate plugin backends. */ 576 char szPath[RTPATH_MAX]; 577 rc = RTPathAppPrivateArch(szPath, sizeof(szPath)); 578 if (RT_FAILURE(rc)) 579 return rc; 580 581 /* To get all entries with VBoxHDD as prefix. */ 582 char *pszPluginFilter; 583 rc = RTStrAPrintf(&pszPluginFilter, "%s/%s*", szPath, 584 VBOX_HDDFORMAT_PLUGIN_PREFIX); 585 if (RT_FAILURE(rc)) 586 { 587 rc = VERR_NO_MEMORY; 588 return rc; 589 } 590 591 PRTDIRENTRYEX pPluginDirEntry = NULL; 592 size_t cbPluginDirEntry = sizeof(RTDIRENTRYEX); 593 /* The plugins are in the same directory as the other shared libs. */ 594 rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT); 595 if (RT_FAILURE(rc)) 596 { 597 /* On Windows the above immediately signals that there are no 598 * files matching, while on other platforms enumerating the 599 * files below fails. Either way: no plugins. */ 600 goto out; 601 } 602 603 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRYEX)); 604 if (!pPluginDirEntry) 605 { 606 rc = VERR_NO_MEMORY; 607 goto out; 608 } 609 610 while ((rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING)) != VERR_NO_MORE_FILES) 611 { 612 RTLDRMOD hPlugin = NIL_RTLDRMOD; 613 PFNVBOXHDDFORMATLOAD pfnHDDFormatLoad = NULL; 614 PVBOXHDDBACKEND pBackend = NULL; 615 char *pszPluginPath = NULL; 616 617 if (rc == VERR_BUFFER_OVERFLOW) 618 { 619 /* allocate new buffer. */ 620 RTMemFree(pPluginDirEntry); 621 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry); 622 /* Retry. */ 623 rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING); 624 if (RT_FAILURE(rc)) 625 break; 626 } 627 else if (RT_FAILURE(rc)) 628 break; 629 630 /* We got the new entry. */ 631 if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode)) 632 continue; 633 634 /* Prepend the path to the libraries. */ 635 rc = RTStrAPrintf(&pszPluginPath, "%s/%s", szPath, pPluginDirEntry->szName); 636 if (RT_FAILURE(rc)) 637 { 638 rc = VERR_NO_MEMORY; 639 break; 640 } 641 642 rc = SUPR3HardenedLdrLoad(pszPluginPath, &hPlugin); 643 if (RT_SUCCESS(rc)) 644 { 645 rc = RTLdrGetSymbol(hPlugin, VBOX_HDDFORMAT_LOAD_NAME, (void**)&pfnHDDFormatLoad); 646 if (RT_FAILURE(rc) || !pfnHDDFormatLoad) 647 { 648 LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnHDDFormat=%#p\n", VBOX_HDDFORMAT_LOAD_NAME, pPluginDirEntry->szName, rc, pfnHDDFormatLoad)); 649 if (RT_SUCCESS(rc)) 650 rc = VERR_SYMBOL_NOT_FOUND; 651 } 652 653 if (RT_SUCCESS(rc)) 654 { 655 /* Get the function table. */ 656 rc = pfnHDDFormatLoad(&pBackend); 657 if (RT_SUCCESS(rc) && pBackend->cbSize == sizeof(VBOXHDDBACKEND)) 658 { 659 pBackend->hPlugin = hPlugin; 660 vdAddBackend(pBackend); 661 } 662 else 663 LogFunc(("ignored plugin '%s': pBackend->cbSize=%d rc=%Rrc\n", pszPluginPath, pBackend->cbSize, rc)); 664 } 665 else 666 LogFunc(("ignored plugin '%s': rc=%Rrc\n", pszPluginPath, rc)); 667 668 if (RT_FAILURE(rc)) 669 RTLdrClose(hPlugin); 670 } 671 RTStrFree(pszPluginPath); 672 } 673 out: 674 if (rc == VERR_NO_MORE_FILES) 675 rc = VINF_SUCCESS; 676 RTStrFree(pszPluginFilter); 677 if (pPluginDirEntry) 678 RTMemFree(pPluginDirEntry); 679 if (pPluginDir) 680 RTDirClose(pPluginDir); 681 return rc; 682 } 683 684 /** 685 * Initializes HDD backends. 686 * 687 * @returns VBox status code. 688 */ 689 VBOXDDU_DECL(int) VDInit() 690 { 691 int rc = vdAddBackends(aStaticBackends, RT_ELEMENTS(aStaticBackends)); 692 if (RT_SUCCESS(rc)) 693 rc = vdLoadDynamicBackends(); 694 LogRel(("VDInit finished\n")); 695 return rc; 696 } 697 698 /** 699 * Destroys loaded HDD backends. 700 * 701 * @returns VBox status code. 702 */ 703 VBOXDDU_DECL(int) VDShutdown() 704 { 705 PVBOXHDDBACKEND *pBackends = g_apBackends; 706 unsigned cBackends = g_cBackends; 707 708 if (!pBackends) 709 return VERR_INTERNAL_ERROR; 710 711 g_cBackends = 0; 712 g_apBackends = NULL; 713 714 for (unsigned i = 0; i < cBackends; i++) 715 if (pBackends[i]->hPlugin != NIL_RTLDRMOD) 716 RTLdrClose(pBackends[i]->hPlugin); 717 return VINF_SUCCESS; 718 } 719 720 721 722 /** 616 723 * Lists all HDD backends and their capabilities in a caller-provided buffer. 617 724 * … … 633 740 634 741 LogFlowFunc(("cEntriesAlloc=%u pEntries=%#p pcEntriesUsed=%#p\n", cEntriesAlloc, pEntries, pcEntriesUsed)); 635 do 636 { 637 /* Check arguments. */ 638 AssertMsgBreakStmt(cEntriesAlloc, 639 ("cEntriesAlloc=%u\n", cEntriesAlloc), 640 rc = VERR_INVALID_PARAMETER); 641 AssertMsgBreakStmt(VALID_PTR(pEntries), 642 ("pEntries=%#p\n", pEntries), 643 rc = VERR_INVALID_PARAMETER); 644 AssertMsgBreakStmt(VALID_PTR(pcEntriesUsed), 645 ("pcEntriesUsed=%#p\n", pcEntriesUsed), 646 rc = VERR_INVALID_PARAMETER); 647 648 /* First enumerate static backends. */ 649 for (unsigned i = 0; aBackends[i] != NULL; i++) 650 { 651 char *pszName = RTStrDup(aBackends[i]->pszBackendName); 652 if (!pszName) 653 { 654 rc = VERR_NO_MEMORY; 655 break; 656 } 657 pEntries[cEntries].pszBackend = pszName; 658 pEntries[cEntries].uBackendCaps = aBackends[i]->uBackendCaps; 659 pEntries[cEntries].papszFileExtensions = aBackends[i]->papszFileExtensions; 660 pEntries[cEntries].paConfigInfo = aBackends[i]->paConfigInfo; 661 cEntries++; 662 if (cEntries >= cEntriesAlloc) 663 { 664 rc = VERR_BUFFER_OVERFLOW; 665 break; 666 } 667 } 668 if (RT_FAILURE(rc)) 669 break; 670 671 /* Then enumerate plugin backends. */ 672 char szPath[RTPATH_MAX]; 673 rc = RTPathAppPrivateArch(szPath, sizeof(szPath)); 674 if (RT_FAILURE(rc)) 675 break; 676 677 /* To get all entries with VBoxHDD as prefix. */ 678 char *pszPluginFilter; 679 rc = RTStrAPrintf(&pszPluginFilter, "%s/%s*", szPath, 680 VBOX_HDDFORMAT_PLUGIN_PREFIX); 681 if (RT_FAILURE(rc)) 682 { 683 rc = VERR_NO_MEMORY; 684 break; 685 } 686 687 /* The plugins are in the same directory as the other shared libs. */ 688 rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT); 689 if (RT_FAILURE(rc)) 690 { 691 /* On Windows the above immediately signals that there are no 692 * files matching, while on other platforms enumerating the 693 * files below fails. Either way: no plugins. */ 694 break; 695 } 696 697 PRTDIRENTRYEX pPluginDirEntry = NULL; 698 size_t cbPluginDirEntry = sizeof(RTDIRENTRY); 699 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRY)); 700 if (!pPluginDirEntry) 701 { 702 rc = VERR_NO_MEMORY; 703 break; 704 } 705 706 while ((rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING)) != VERR_NO_MORE_FILES) 707 { 708 RTLDRMOD hPlugin = NIL_RTLDRMOD; 709 PFNVBOXHDDFORMATLOAD pfnHDDFormatLoad = NULL; 710 PVBOXHDDBACKEND pBackend = NULL; 711 char *pszPluginPath = NULL; 712 713 if (rc == VERR_BUFFER_OVERFLOW) 714 { 715 /* allocate new buffer. */ 716 RTMemFree(pPluginDirEntry); 717 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry); 718 /* Retry. */ 719 rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING); 720 if (RT_FAILURE(rc)) 721 break; 722 } 723 else if (RT_FAILURE(rc)) 724 break; 725 726 /* We got the new entry. */ 727 if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode)) 728 continue; 729 730 /* Prepend the path to the libraries. */ 731 rc = RTStrAPrintf(&pszPluginPath, "%s/%s", szPath, pPluginDirEntry->szName); 732 if (RT_FAILURE(rc)) 733 { 734 rc = VERR_NO_MEMORY; 735 break; 736 } 737 738 rc = SUPR3HardenedLdrLoad(pszPluginPath, &hPlugin); 739 if (RT_SUCCESS(rc)) 740 { 741 rc = RTLdrGetSymbol(hPlugin, VBOX_HDDFORMAT_LOAD_NAME, (void**)&pfnHDDFormatLoad); 742 if (RT_FAILURE(rc) || !pfnHDDFormatLoad) 743 { 744 LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnHDDFormat=%#p\n", VBOX_HDDFORMAT_LOAD_NAME, pPluginDirEntry->szName, rc, pfnHDDFormatLoad)); 745 if (RT_SUCCESS(rc)) 746 rc = VERR_SYMBOL_NOT_FOUND; 747 } 748 749 if (RT_SUCCESS(rc)) 750 { 751 /* Get the function table. */ 752 rc = pfnHDDFormatLoad(&pBackend); 753 if (RT_SUCCESS(rc) && pBackend->cbSize == sizeof(VBOXHDDBACKEND)) 754 { 755 char *pszName = RTStrDup(pBackend->pszBackendName); 756 if (!pszName) 757 { 758 rc = VERR_NO_MEMORY; 759 break; 760 } 761 pEntries[cEntries].pszBackend = pszName; 762 pEntries[cEntries].uBackendCaps = pBackend->uBackendCaps; 763 unsigned cExts, iExt; 764 for (cExts=0; pBackend->papszFileExtensions[cExts]; cExts++) 765 ; 766 const char **paExts = (const char **)RTMemAlloc((cExts+1) * sizeof(paExts[0])); /** @todo rainy day: fix leak on error. */ 767 if (!paExts) 768 { 769 rc = VERR_NO_MEMORY; 770 break; 771 } 772 for (iExt=0; iExt < cExts; iExt++) 773 { 774 paExts[iExt] = (const char*)RTStrDup(pBackend->papszFileExtensions[iExt]); 775 if (!paExts[iExt]) 776 { 777 rc = VERR_NO_MEMORY; 778 break; 779 } 780 } 781 paExts[iExt] = NULL; 782 pEntries[cEntries].papszFileExtensions = paExts; 783 if (pBackend->paConfigInfo != NULL) 784 { 785 /* copy the whole config field! */ 786 rc = VERR_NOT_IMPLEMENTED; 787 break; 788 } 789 pEntries[cEntries].paConfigInfo = NULL; 790 cEntries++; 791 if (cEntries >= cEntriesAlloc) 792 { 793 rc = VERR_BUFFER_OVERFLOW; 794 break; 795 } 796 } 797 else 798 LogFunc(("ignored plugin '%s': pBackend->cbSize=%d rc=%Rrc\n", pszPluginPath, pBackend->cbSize, rc)); 799 } 800 else 801 LogFunc(("ignored plugin '%s': rc=%Rrc\n", pszPluginPath, rc)); 802 803 RTLdrClose(hPlugin); 804 } 805 RTStrFree(pszPluginPath); 806 } 807 if (rc == VERR_NO_MORE_FILES) 808 rc = VINF_SUCCESS; 809 RTStrFree(pszPluginFilter); 810 if (pPluginDirEntry) 811 RTMemFree(pPluginDirEntry); 812 if (pPluginDir) 813 RTDirClose(pPluginDir); 814 } while (0); 815 /* Ignore any files which can't be found. Happens e.g. on Windows when 816 * absolutely no plugins are installed (see above). Totally harmless. */ 817 if (rc == VERR_FILE_NOT_FOUND) 818 rc = VINF_SUCCESS; 742 /* Check arguments. */ 743 AssertMsgReturn(cEntriesAlloc, 744 ("cEntriesAlloc=%u\n", cEntriesAlloc), 745 VERR_INVALID_PARAMETER); 746 AssertMsgReturn(VALID_PTR(pEntries), 747 ("pEntries=%#p\n", pEntries), 748 VERR_INVALID_PARAMETER); 749 AssertMsgReturn(VALID_PTR(pcEntriesUsed), 750 ("pcEntriesUsed=%#p\n", pcEntriesUsed), 751 VERR_INVALID_PARAMETER); 752 if (!g_apBackends) 753 VDInit(); 754 755 if (cEntriesAlloc < g_cBackends) 756 { 757 *pcEntriesUsed = g_cBackends; 758 return VERR_BUFFER_OVERFLOW; 759 } 760 761 for (unsigned i = 0; i < g_cBackends; i++) 762 { 763 pEntries[i].pszBackend = g_apBackends[i]->pszBackendName; 764 pEntries[i].uBackendCaps = g_apBackends[i]->uBackendCaps; 765 pEntries[i].papszFileExtensions = g_apBackends[i]->papszFileExtensions; 766 pEntries[i].paConfigInfo = g_apBackends[i]->paConfigInfo; 767 } 819 768 820 769 LogFlowFunc(("returns %Rrc *pcEntriesUsed=%u\n", rc, cEntries)); 821 *pcEntriesUsed = cEntries;770 *pcEntriesUsed = g_cBackends; 822 771 return rc; 823 772 } … … 833 782 VBOXDDU_DECL(int) VDBackendInfoOne(const char *pszBackend, PVDBACKENDINFO pEntry) 834 783 { 835 return VERR_NOT_IMPLEMENTED; 784 LogFlowFunc(("pszBackend=%#p pEntry=%#p\n", pszBackend, pEntry)); 785 /* Check arguments. */ 786 AssertMsgReturn(VALID_PTR(pszBackend), 787 ("pszBackend=%#p\n", pszBackend), 788 VERR_INVALID_PARAMETER); 789 AssertMsgReturn(VALID_PTR(pEntry), 790 ("pEntry=%#p\n", pEntry), 791 VERR_INVALID_PARAMETER); 792 if (!g_apBackends) 793 VDInit(); 794 795 /* Go through loaded backends. */ 796 for (unsigned i = 0; i < g_cBackends; i++) 797 { 798 if (!strcmp(pszBackend, g_apBackends[i]->pszBackendName)) 799 { 800 pEntry->pszBackend = g_apBackends[i]->pszBackendName; 801 pEntry->uBackendCaps = g_apBackends[i]->uBackendCaps; 802 pEntry->papszFileExtensions = g_apBackends[i]->papszFileExtensions; 803 pEntry->paConfigInfo = g_apBackends[i]->paConfigInfo; 804 return VINF_SUCCESS; 805 } 806 } 807 808 return VERR_NOT_FOUND; 836 809 } 837 810 … … 924 897 VBOXDDU_DECL(int) VDGetFormat(const char *pszFilename, char **ppszFormat) 925 898 { 926 PRTDIR pPluginDir = NULL;927 899 int rc = VERR_NOT_SUPPORTED; 928 bool fPluginFound = false;929 900 930 901 LogFlowFunc(("pszFilename=\"%s\"\n", pszFilename)); 931 do 932 { 933 /* Check arguments. */ 934 AssertMsgBreakStmt(VALID_PTR(pszFilename) && *pszFilename, 935 ("pszFilename=%#p \"%s\"\n", pszFilename, pszFilename), 936 rc = VERR_INVALID_PARAMETER); 937 AssertMsgBreakStmt(VALID_PTR(ppszFormat), 938 ("ppszFormat=%#p\n", ppszFormat), 939 rc = VERR_INVALID_PARAMETER); 940 941 /* First check if static backends support this file format. */ 942 for (unsigned i = 0; aBackends[i] != NULL; i++) 943 { 944 if (aBackends[i]->pfnCheckIfValid) 902 /* Check arguments. */ 903 AssertMsgReturn(VALID_PTR(pszFilename) && *pszFilename, 904 ("pszFilename=%#p \"%s\"\n", pszFilename, pszFilename), 905 VERR_INVALID_PARAMETER); 906 AssertMsgReturn(VALID_PTR(ppszFormat), 907 ("ppszFormat=%#p\n", ppszFormat), 908 VERR_INVALID_PARAMETER); 909 910 if (!g_apBackends) 911 VDInit(); 912 913 /* Find the backend supporting this file format. */ 914 for (unsigned i = 0; i < g_cBackends; i++) 915 { 916 if (g_apBackends[i]->pfnCheckIfValid) 917 { 918 rc = g_apBackends[i]->pfnCheckIfValid(pszFilename); 919 if (RT_SUCCESS(rc)) 945 920 { 946 rc = aBackends[i]->pfnCheckIfValid(pszFilename); 947 if (RT_SUCCESS(rc)) 921 /* Copy the name into the new string. */ 922 char *pszFormat = RTStrDup(g_apBackends[i]->pszBackendName); 923 if (!pszFormat) 948 924 { 949 fPluginFound = true; 950 /* Copy the name into the new string. */ 951 char *pszFormat = RTStrDup(aBackends[i]->pszBackendName); 952 if (!pszFormat) 953 { 954 rc = VERR_NO_MEMORY; 955 break; 956 } 957 *ppszFormat = pszFormat; 925 rc = VERR_NO_MEMORY; 958 926 break; 959 927 } 960 } 961 } 962 if (fPluginFound) 963 break; 964 965 /* Then check if plugin backends support this file format. */ 966 char szPath[RTPATH_MAX]; 967 rc = RTPathAppPrivateArch(szPath, sizeof(szPath)); 968 if (RT_FAILURE(rc)) 969 break; 970 971 /* To get all entries with VBoxHDD as prefix. */ 972 char *pszPluginFilter; 973 rc = RTStrAPrintf(&pszPluginFilter, "%s/%s*", szPath, 974 VBOX_HDDFORMAT_PLUGIN_PREFIX); 975 if (RT_FAILURE(rc)) 976 { 977 rc = VERR_NO_MEMORY; 978 break; 979 } 980 981 /* The plugins are in the same directory as the other shared libs. */ 982 rc = RTDirOpenFiltered(&pPluginDir, pszPluginFilter, RTDIRFILTER_WINNT); 983 if (RT_FAILURE(rc)) 984 { 985 if (rc == VERR_FILE_NOT_FOUND) 986 { 987 /* VERR_FILE_NOT_FOUND would be interpreted as the hard 988 * disk storage unit was not found, so replace with 989 * VERR_NOT_SUPPORTED which is more meaningful in this case */ 990 rc = VERR_NOT_SUPPORTED; 991 } 992 break; 993 } 994 995 PRTDIRENTRYEX pPluginDirEntry = NULL; 996 size_t cbPluginDirEntry = sizeof(RTDIRENTRY); 997 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(sizeof(RTDIRENTRY)); 998 if (!pPluginDirEntry) 999 { 1000 rc = VERR_NO_MEMORY; 1001 break; 1002 } 1003 1004 while ((rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING)) != VERR_NO_MORE_FILES) 1005 { 1006 RTLDRMOD hPlugin = NIL_RTLDRMOD; 1007 PFNVBOXHDDFORMATLOAD pfnHDDFormatLoad = NULL; 1008 PVBOXHDDBACKEND pBackend = NULL; 1009 char *pszPluginPath = NULL; 1010 1011 if (rc == VERR_BUFFER_OVERFLOW) 1012 { 1013 /* allocate new buffer. */ 1014 RTMemFree(pPluginDirEntry); 1015 pPluginDirEntry = (PRTDIRENTRYEX)RTMemAllocZ(cbPluginDirEntry); 1016 /* Retry. */ 1017 rc = RTDirReadEx(pPluginDir, pPluginDirEntry, &cbPluginDirEntry, RTFSOBJATTRADD_NOTHING); 1018 if (RT_FAILURE(rc)) 1019 break; 1020 } 1021 else if (RT_FAILURE(rc)) 1022 break; 1023 1024 /* We got the new entry. */ 1025 if (!RTFS_IS_FILE(pPluginDirEntry->Info.Attr.fMode)) 1026 continue; 1027 1028 /* Prepend the path to the libraries. */ 1029 rc = RTStrAPrintf(&pszPluginPath, "%s/%s", szPath, pPluginDirEntry->szName); 1030 if (RT_FAILURE(rc)) 1031 { 1032 rc = VERR_NO_MEMORY; 928 *ppszFormat = pszFormat; 929 rc = VINF_SUCCESS; 1033 930 break; 1034 931 } 1035 1036 rc = SUPR3HardenedLdrLoad(pszPluginPath, &hPlugin); 1037 if (RT_SUCCESS(rc)) 1038 { 1039 rc = RTLdrGetSymbol(hPlugin, VBOX_HDDFORMAT_LOAD_NAME, (void**)&pfnHDDFormatLoad); 1040 if (RT_FAILURE(rc) || !pfnHDDFormatLoad) 1041 { 1042 LogFunc(("error resolving the entry point %s in plugin %s, rc=%Rrc, pfnHDDFormat=%#p\n", VBOX_HDDFORMAT_LOAD_NAME, pPluginDirEntry->szName, rc, pfnHDDFormatLoad)); 1043 if (RT_SUCCESS(rc)) 1044 rc = VERR_SYMBOL_NOT_FOUND; 1045 } 1046 1047 if (RT_SUCCESS(rc)) 1048 { 1049 /* Get the function table. */ 1050 rc = pfnHDDFormatLoad(&pBackend); 1051 if (RT_SUCCESS(rc) && pBackend->cbSize == sizeof(VBOXHDDBACKEND)) 1052 { 1053 1054 /* Check if the plugin can handle this file. */ 1055 rc = pBackend->pfnCheckIfValid(pszFilename); 1056 if (RT_SUCCESS(rc)) 1057 { 1058 fPluginFound = true; 1059 rc = VINF_SUCCESS; 1060 1061 /* Report the format name. */ 1062 RTPathStripExt(pPluginDirEntry->szName); 1063 AssertBreakStmt(strlen(pPluginDirEntry->szName) > VBOX_HDDFORMAT_PLUGIN_PREFIX_LENGTH, 1064 rc = VERR_INVALID_NAME); 1065 1066 char *pszFormat = NULL; 1067 pszFormat = RTStrDup(pPluginDirEntry->szName + VBOX_HDDFORMAT_PLUGIN_PREFIX_LENGTH); 1068 if (!pszFormat) 1069 rc = VERR_NO_MEMORY; 1070 1071 *ppszFormat = pszFormat; 1072 } 1073 } 1074 } 1075 else 1076 pBackend = NULL; 1077 1078 RTLdrClose(hPlugin); 1079 } 1080 RTStrFree(pszPluginPath); 1081 1082 /* 1083 * We take the first plugin which can handle this file. 1084 */ 1085 if (fPluginFound) 1086 break; 1087 } 1088 if (rc == VERR_NO_MORE_FILES) 1089 rc = VERR_NOT_SUPPORTED; 1090 1091 RTStrFree(pszPluginFilter); 1092 if (pPluginDirEntry) 1093 RTMemFree(pPluginDirEntry); 1094 if (pPluginDir) 1095 RTDirClose(pPluginDir); 1096 } while (0); 932 } 933 } 1097 934 1098 935 LogFlowFunc(("returns %Rrc *ppszFormat=\"%s\"\n", rc, *ppszFormat)); … … 1161 998 pImage->pVDIfsImage = pVDIfsImage; 1162 999 1163 rc = vdFindBackend(pszBackend, &pImage->Backend , &pImage->hPlugin);1000 rc = vdFindBackend(pszBackend, &pImage->Backend); 1164 1001 if (RT_FAILURE(rc)) 1165 1002 break; … … 1313 1150 if (pImage) 1314 1151 { 1315 if (pImage->hPlugin != NIL_RTLDRMOD)1316 RTLdrClose(pImage->hPlugin);1317 1318 1152 if (pImage->pszFilename) 1319 1153 RTStrFree(pImage->pszFilename); … … 1439 1273 pImage->pVDIfsImage = pVDIfsImage; 1440 1274 1441 rc = vdFindBackend(pszBackend, &pImage->Backend , &pImage->hPlugin);1275 rc = vdFindBackend(pszBackend, &pImage->Backend); 1442 1276 if (RT_FAILURE(rc)) 1443 1277 break; … … 1546 1380 if (pImage) 1547 1381 { 1548 if (pImage->hPlugin != NIL_RTLDRMOD)1549 RTLdrClose(pImage->hPlugin);1550 1551 1382 if (pImage->pszFilename) 1552 1383 RTStrFree(pImage->pszFilename); … … 1641 1472 } 1642 1473 1643 rc = vdFindBackend(pszBackend, &pImage->Backend , &pImage->hPlugin);1474 rc = vdFindBackend(pszBackend, &pImage->Backend); 1644 1475 if (RT_FAILURE(rc)) 1645 1476 break; … … 1739 1570 if (RT_FAILURE(rc)) 1740 1571 { 1741 if (pImage->hPlugin != NIL_RTLDRMOD)1742 RTLdrClose(pImage->hPlugin);1743 1744 1572 if (pImage) 1745 1573 { … … 2103 1931 pImageFrom->pvBackendData = NULL; 2104 1932 2105 if (pImageFrom->hPlugin != NIL_RTLDRMOD)2106 RTLdrClose(pImageFrom->hPlugin);2107 2108 1933 if (pImageFrom->pszFilename) 2109 1934 RTStrFree(pImageFrom->pszFilename); … … 2230 2055 2231 2056 /* Free remaining resources. */ 2232 if (pImageFrom->hPlugin != NIL_RTLDRMOD)2233 RTLdrClose(pImageFrom->hPlugin);2234 2235 2057 if (pImageFrom->pszFilename) 2236 2058 RTStrFree(pImageFrom->pszFilename); … … 2251 2073 2252 2074 /* Free remaining resources. */ 2253 if (pImageTo->hPlugin != NIL_RTLDRMOD)2254 RTLdrClose(pImageTo->hPlugin);2255 2256 2075 if (pImageTo->pszFilename) 2257 2076 RTStrFree(pImageTo->pszFilename); … … 2307 2126 rc = pImage->Backend->pfnClose(pImage->pvBackendData, fDelete); 2308 2127 /* Free remaining resources related to the image. */ 2309 if (pImage->hPlugin != NIL_RTLDRMOD)2310 {2311 RTLdrClose(pImage->hPlugin);2312 pImage->hPlugin = NIL_RTLDRMOD;2313 }2314 2128 RTStrFree(pImage->pszFilename); 2315 2129 RTMemFree(pImage); … … 2401 2215 rc = rc2; 2402 2216 /* Free remaining resources related to the image. */ 2403 if (pImage->hPlugin != NIL_RTLDRMOD)2404 {2405 RTLdrClose(pImage->hPlugin);2406 pImage->hPlugin = NIL_RTLDRMOD;2407 }2408 2217 RTStrFree(pImage->pszFilename); 2409 2218 RTMemFree(pImage); -
trunk/src/VBox/Devices/Storage/VBoxHDD-newInternal.h
r11484 r14852 70 70 */ 71 71 PCVDCONFIGINFO paConfigInfo; 72 73 /** 74 * Handle of loaded plugin library, NIL_RTLDRMOD for static backends. 75 */ 76 RTLDRMOD hPlugin; 72 77 73 78 /** -
trunk/src/VBox/Devices/Storage/VDIHDDCore.cpp
r14270 r14852 1869 1869 /* paConfigInfo */ 1870 1870 NULL, 1871 /* hPlugin */ 1872 NIL_RTLDRMOD, 1871 1873 /* pfnCheckIfValid */ 1872 1874 vdiCheckIfValid, -
trunk/src/VBox/Devices/Storage/VHDHDDCore.cpp
r14321 r14852 1868 1868 /* paConfigInfo */ 1869 1869 NULL, 1870 /* hPlugin */ 1871 NIL_RTLDRMOD, 1870 1872 /* pfnCheckIfValid */ 1871 1873 vhdCheckIfValid, -
trunk/src/VBox/Devices/Storage/VmdkHDDCore.cpp
r14302 r14852 5317 5317 /* paConfigInfo */ 5318 5318 NULL, 5319 /* hPlugin */ 5320 NIL_RTLDRMOD, 5319 5321 /* pfnCheckIfValid */ 5320 5322 vmdkCheckIfValid, -
trunk/src/VBox/Main/VirtualBoxImpl.cpp
r14783 r14852 489 489 # error "Port me!" 490 490 #endif 491 /* Unload plugin backends. */ 492 VDShutdown(); 491 493 492 494 LogFlowThisFuncLeave();
Note:
See TracChangeset
for help on using the changeset viewer.