@@ -260,46 +260,19 @@ bool BootWimProcessor::mountAndProcessWim(const std::string &bootWimDest, const
260260 bool isPecmdPE = (GetFileAttributesA (pecmdExe.c_str ()) != INVALID_FILE_ATTRIBUTES) &&
261261 (GetFileAttributesA (pecmdIni.c_str ()) != INVALID_FILE_ATTRIBUTES);
262262
263- // For PECMD PEs (Hiren's), extract Programs and CustomDrivers to data partition, NOT to boot.wim
263+ // For PECMD PEs in RAM mode: we WILL integrate Programs into boot.wim at X:\Programs
264+ // Then we'll add "subst Y: X:\" to pecmd.ini so Y:\Programs will work transparently
264265 if (isPecmdPE) {
265- logFile << ISOCopyManager::getTimestamp () << " PECMD PE detected, extracting Programs and CustomDrivers to data partition" << std::endl;
266- eventManager_.notifyLogUpdate (" PECMD PE detectado: extrayendo Programs y CustomDrivers a particion de datos...\r\n " );
267-
268- // Extract Programs to data partition
269- std::string programsDataDest = destPath + " Programs" ;
270- if (GetFileAttributesA (programsDataDest.c_str ()) == INVALID_FILE_ATTRIBUTES) {
271- eventManager_.notifyDetailedProgress (35 , 100 , " Extrayendo Programs a particion de datos" );
272- if (isoReader_->extractDirectory (sourcePath, " Programs" , programsDataDest)) {
273- logFile << ISOCopyManager::getTimestamp () << " Programs extracted to data partition: " << programsDataDest << std::endl;
274- eventManager_.notifyLogUpdate (" Programs extraido a particion de datos (Y:\\ Programs).\r\n " );
275- } else {
276- logFile << ISOCopyManager::getTimestamp () << " Programs directory not found in ISO or extraction failed" << std::endl;
277- eventManager_.notifyLogUpdate (" Advertencia: Programs no encontrado en ISO.\r\n " );
278- }
279- } else {
280- logFile << ISOCopyManager::getTimestamp () << " Programs already exists on data partition" << std::endl;
281- }
282-
283- // Extract CustomDrivers to data partition
284- std::string customDriversDataDest = destPath + " CustomDrivers" ;
285- if (GetFileAttributesA (customDriversDataDest.c_str ()) == INVALID_FILE_ATTRIBUTES) {
286- eventManager_.notifyDetailedProgress (38 , 100 , " Extrayendo CustomDrivers a particion de datos" );
287- if (isoReader_->extractDirectory (sourcePath, " CustomDrivers" , customDriversDataDest)) {
288- logFile << ISOCopyManager::getTimestamp () << " CustomDrivers extracted to data partition: " << customDriversDataDest << std::endl;
289- eventManager_.notifyLogUpdate (" CustomDrivers extraido a particion de datos (Y:\\ CustomDrivers).\r\n " );
290- } else {
291- logFile << ISOCopyManager::getTimestamp () << " CustomDrivers directory not found in ISO or extraction failed" << std::endl;
292- eventManager_.notifyLogUpdate (" Advertencia: CustomDrivers no encontrado en ISO.\r\n " );
293- }
294- } else {
295- logFile << ISOCopyManager::getTimestamp () << " CustomDrivers already exists on data partition" << std::endl;
296- }
266+ logFile << ISOCopyManager::getTimestamp ()
267+ << " PECMD PE detected: will integrate Programs/CustomDrivers into boot.wim and map Y: -> X:"
268+ << std::endl;
269+ eventManager_.notifyLogUpdate (" PECMD PE detectado: integrando contenido en boot.wim para modo RAM...\r\n " );
297270 }
298271
299272 if (mountCode == 0 ) {
300- // CRITICAL: For PECMD-based PEs like Hiren's, do NOT integrate Programs into boot.wim
301- // PECMD expects Programs to be on the Y: drive (data partition), not in the ramdisk
302- if (integratePrograms && !isPecmdPE ) {
273+ // CRITICAL: For PECMD-based PEs like Hiren's in RAM mode, DO integrate Programs into boot.wim
274+ // We'll add "subst Y: X:\" to pecmd.ini so Y:\Programs will map to X:\Programs
275+ if (integratePrograms) {
303276 eventManager_.notifyDetailedProgress (40 , 100 , " Integrando Programs en boot.wim" );
304277 eventManager_.notifyLogUpdate (" Integrando Programs en boot.wim...\r\n " );
305278 eventManager_.notifyDetailedProgress (0 , 0 , " Integrando Programs en boot.wim..." );
@@ -352,18 +325,11 @@ bool BootWimProcessor::mountAndProcessWim(const std::string &bootWimDest, const
352325 // If Programs is not present in source or ISO, just skip silently with an info message
353326 eventManager_.notifyLogUpdate (" Carpeta 'Programs' no encontrada; se omite su integracion.\r\n " );
354327 }
355- } else if (integratePrograms && isPecmdPE) {
356- // For PECMD-based PEs (Hiren's), Programs must stay on the data partition (Y:), not in boot.wim
357- logFile << ISOCopyManager::getTimestamp ()
358- << " PECMD PE detected: skipping Programs injection into boot.wim (Programs must be on Y: drive)"
359- << std::endl;
360- eventManager_.notifyLogUpdate (
361- " PECMD detectado: Programs NO se integra en boot.wim (debe estar en partición de datos Y:).\r\n " );
362328 }
363329
364- // Integrate CustomDrivers - but NOT for PECMD-based PEs
365- // For Hiren's, CustomDrivers are loaded directly from Y:\CustomDrivers by PECMD
366- if (!isPecmdPE) {
330+ // Integrate CustomDrivers into boot.wim (including for PECMD PEs in RAM mode)
331+ // We'll add "subst Y: X:\" to pecmd.ini so Y:\CustomDrivers will map to X:\CustomDrivers
332+ {
367333 // NOTE: Stage drivers OUTSIDE the mounted image and let DISM publish them into the image.
368334 // Keeping a raw "CustomDrivers" folder inside the image is not required and only adds size.
369335 std::filesystem::path customDriversStage;
@@ -450,34 +416,20 @@ bool BootWimProcessor::mountAndProcessWim(const std::string &bootWimDest, const
450416 // Cleanup staging folder
451417 std::error_code rmStgEc; std::filesystem::remove_all (customDriversStage, rmStgEc);
452418 }
453- } else {
454- // For PECMD-based PEs, do not integrate CustomDrivers into boot.wim
455- // PECMD loads them directly from Y:\CustomDrivers via pnputil commands in pecmd.ini
456- logFile << ISOCopyManager::getTimestamp ()
457- << " PECMD PE detected: skipping CustomDrivers injection into boot.wim (loaded from Y: by PECMD)"
458- << std::endl;
459- eventManager_.notifyLogUpdate (
460- " PECMD detectado: CustomDrivers NO se integra en boot.wim (PECMD los carga desde Y:\\ CustomDrivers).\r\n " );
461419 }
462420
463- // Integrate critical system drivers from the current machine (NOT for PECMD PEs)
464- if (!isPecmdPE) {
465- eventManager_.notifyDetailedProgress (47 , 100 , " Integrando controladores locales en boot.wim" );
466- if (integrateSystemDriversIntoMountedImage (mountDir, logFile)) {
467- eventManager_.notifyLogUpdate (" Controladores del sistema integrados en boot.wim.\r\n " );
468- } else {
469- eventManager_.notifyLogUpdate (
470- " Advertencia: No se pudieron integrar todos los controladores locales en boot.wim.\r\n " );
471- }
472- eventManager_.notifyDetailedProgress (0 , 0 , " " );
421+ // Integrate critical system drivers from the current machine
422+ eventManager_.notifyDetailedProgress (47 , 100 , " Integrando controladores locales en boot.wim" );
423+ if (integrateSystemDriversIntoMountedImage (mountDir, logFile)) {
424+ eventManager_.notifyLogUpdate (" Controladores del sistema integrados en boot.wim.\r\n " );
473425 } else {
474- logFile << ISOCopyManager::getTimestamp ()
475- << " PECMD PE detected: skipping system drivers integration (PECMD handles drivers) " << std::endl ;
426+ eventManager_. notifyLogUpdate (
427+ " Advertencia: No se pudieron integrar todos los controladores locales en boot.wim. \r\n " ) ;
476428 }
429+ eventManager_.notifyDetailedProgress (0 , 0 , " " );
477430
478- // Copy and configure .ini files (but NOT for PECMD PEs - they have their own config)
479- if (!isPecmdPE) {
480- eventManager_.notifyDetailedProgress (55 , 100 , " Copiando y reconfigurando archivos .ini" );
431+ // Copy and configure .ini files
432+ eventManager_.notifyDetailedProgress (55 , 100 , " Copiando y reconfigurando archivos .ini" );
481433 IniConfigurator iniConfigurator;
482434 // First, reconfigure any existing .ini files in the mounted boot.wim
483435 WIN32_FIND_DATAA findDataExisting;
@@ -567,10 +519,6 @@ bool BootWimProcessor::mountAndProcessWim(const std::string &bootWimDest, const
567519
568520 eventManager_.notifyLogUpdate (" Archivos .ini integrados y reconfigurados en boot.wim correctamente.\r\n " );
569521 }
570- } else {
571- logFile << ISOCopyManager::getTimestamp ()
572- << " PECMD PE detected: skipping .ini file injection (PECMD has its own configuration)" << std::endl;
573- }
574522
575523 // Ensure Windows\System32 exists and handle startnet.cmd content
576524 std::string windowsDir = mountDir + " \\ Windows" ;
@@ -609,8 +557,8 @@ bool BootWimProcessor::mountAndProcessWim(const std::string &bootWimDest, const
609557 if (hasPecmd) {
610558 eventManager_.notifyLogUpdate (" Hiren's BootCD PE detectado (PECMD presente).\r\n " );
611559
612- // For Hiren's BootCD PE: Copy HBCD_PE.ini from ISO root to DATA PARTITION ROOT (not boot.wim)
613- // LetterSwap.exe expects this file at Y:\HBCD_PE.ini (data partition root )
560+ // For Hiren's BootCD PE: Copy HBCD_PE.ini from ISO root to BOOT.WIM ROOT
561+ // Since we're using "subst Y: X:\", LetterSwap.exe will find it at Y:\HBCD_PE.ini (which points to X:\HBCD_PE.ini )
614562 std::string hbcdIniInISO = sourcePath;
615563 // sourcePath is the ISO path, need to check if HBCD_PE.ini exists in root
616564 std::vector<std::string> isoRootFiles;
@@ -631,15 +579,15 @@ bool BootWimProcessor::mountAndProcessWim(const std::string &bootWimDest, const
631579 }
632580
633581 if (foundHBCDini) {
634- // Extract to DATA PARTITION ROOT, not to boot.wim
635- std::string hbcdIniDest = destPath + " HBCD_PE.ini" ;
582+ // Extract to BOOT.WIM ROOT (X:\HBCD_PE.ini), accessible as Y:\HBCD_PE.ini via subst
583+ std::string hbcdIniDest = mountDir + " \\ HBCD_PE.ini" ;
636584 logFile << ISOCopyManager::getTimestamp ()
637- << " Found HBCD_PE.ini in ISO root, extracting to data partition root..." << std::endl;
585+ << " Found HBCD_PE.ini in ISO root, extracting to boot.wim root..." << std::endl;
638586
639587 if (isoReader_->extractFile (sourcePath, " HBCD_PE.ini" , hbcdIniDest)) {
640588 logFile << ISOCopyManager::getTimestamp ()
641- << " HBCD_PE.ini copied successfully to data partition : " << hbcdIniDest << std::endl;
642- eventManager_.notifyLogUpdate (" HBCD_PE.ini extraido a particion de datos ( Y:\\ HBCD_PE.ini).\r\n " );
589+ << " HBCD_PE.ini copied successfully to boot.wim root : " << hbcdIniDest << std::endl;
590+ eventManager_.notifyLogUpdate (" HBCD_PE.ini integrado en boot.wim (accesible como Y:\\ HBCD_PE.ini via subst ).\r\n " );
643591 } else {
644592 logFile << ISOCopyManager::getTimestamp ()
645593 << " Failed to extract HBCD_PE.ini from ISO" << std::endl;
@@ -649,13 +597,50 @@ bool BootWimProcessor::mountAndProcessWim(const std::string &bootWimDest, const
649597 << " HBCD_PE.ini not found in ISO root (normal for some PE variants)" << std::endl;
650598 }
651599
652- // Important: Do NOT modify startnet.cmd for Hiren's PECMD-based PE
653- // PECMD.ini handles the entire boot process automatically via winpeshl.ini
600+ // For PECMD PE in RAM mode: modify pecmd.ini to map Y: -> X: using subst
601+ // This allows PECMD scripts to work without changes (Y:\Programs still works)
654602 logFile << ISOCopyManager::getTimestamp ()
655- << " Hiren's/PECMD PE detected: preserving startnet.cmd and pecmd.ini without modification "
603+ << " Hiren's/PECMD PE detected in RAM mode: adding Y: -> X: drive mapping to pecmd.ini"
656604 << std::endl;
605+
606+ // Read existing pecmd.ini
607+ std::ifstream pecmdIn (pecmdIni, std::ios::binary);
608+ std::string pecmdContent;
609+ if (pecmdIn) {
610+ pecmdContent.assign ((std::istreambuf_iterator<char >(pecmdIn)), std::istreambuf_iterator<char >());
611+ pecmdIn.close ();
612+
613+ // Insert SUBST Y: X:\ command at the very beginning (after first line which is usually {ENTER:...})
614+ // Find the first newline
615+ size_t firstNewline = pecmdContent.find (' \n ' );
616+ if (firstNewline != std::string::npos) {
617+ // Insert after the first line (ENTER line)
618+ std::string substCmd = " // BootThatISO: Map Y: to X: for RAM boot mode\r\n "
619+ " EXEC @!X:\\ Windows\\ System32\\ subst.exe Y: X:\\\r\n "
620+ " WAIT 500\r\n\r\n " ;
621+ pecmdContent.insert (firstNewline + 1 , substCmd);
622+
623+ // Write modified pecmd.ini back
624+ std::ofstream pecmdOut (pecmdIni, std::ios::binary | std::ios::trunc);
625+ if (pecmdOut) {
626+ pecmdOut.write (pecmdContent.data (), (std::streamsize)pecmdContent.size ());
627+ pecmdOut.flush ();
628+ logFile << ISOCopyManager::getTimestamp ()
629+ << " Added 'subst Y: X:\\ ' command to pecmd.ini for RAM boot compatibility"
630+ << std::endl;
631+ eventManager_.notifyLogUpdate (" Mapeo Y: -> X: agregado a pecmd.ini para modo RAM.\r\n " );
632+ }
633+ } else {
634+ logFile << ISOCopyManager::getTimestamp ()
635+ << " Warning: Could not find insertion point in pecmd.ini" << std::endl;
636+ }
637+ } else {
638+ logFile << ISOCopyManager::getTimestamp ()
639+ << " Warning: Could not read pecmd.ini for modification" << std::endl;
640+ }
641+
657642 eventManager_.notifyLogUpdate (
658- " PECMD detectado: configuración original preservada (PECMD maneja el arranque automáticamente ).\r\n " );
643+ " PECMD configurado para modo RAM (Y: apuntará a X: ).\r\n " );
659644 } else {
660645 // For non-PECMD PEs, handle startnet.cmd normally
661646 bool startnetExists = fileExists (startnetPath);
0 commit comments