Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Lire des secteurs d'un CD

31 réponses
Avatar
Yoshito
Salut à tous

Je cherche à lire les secteurs d'un CD : on m'a dit de venir ici car
apparement vous êtes les meilleurs.

J'ai utilisé la fonction createfile puis deviceiocontrol, jusqu'ici aucuns
problèmes, j'ai pu récupérer la géométrie du CD.

C'est après que ça se corse, j'utilise ReadFile, ça ne marche pas, et
j'obtiens en permanence l'erreur 87 avec getlasterror, erreur qui dit qu'un
des paramètres est incorrect.

que dois-je faire ??

merci de laide.

Voici le code :

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winioctl.h>
#define CD "\\\\.\\e:"

int main()
{
HANDLE cdrom;
LPVOID *t;
BOOL resultat;
DWORD truc, truc2 = 0;
DISK_GEOMETRY buff;
unsigned char i;
char buffer[256];
printf("%p",buffer);


cdrom = CreateFile(CD, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);

if(cdrom == INVALID_HANDLE_VALUE) // cannot open the drive
{
MessageBox(NULL, "Le lecteur que vous avez indiqué est impossible à
ouvrir pour une raison absolument inconnue :p\nVous avez sans doute mal tapé
la lettre du lecteur.", "Erreur d'ouverture", MB_ICONEXCLAMATION);
return (FALSE);
}

resultat = DeviceIoControl(cdrom, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL,
0, &buff, sizeof(buff), &truc, NULL);

if(resultat)
{
printf("%s :\n", CD);
printf("- Cylindres = %ld\n", buff.Cylinders);
printf("- Pistes/Cylindres = %ld\n", (ULONG)
buff.TracksPerCylinder);
printf("- Secteurs/Pistes = %ld\n", (ULONG) buff.SectorsPerTrack);
printf("- Octets/Secteurs = %ld\n", (ULONG) buff.BytesPerSector);
printf("\n");
}
else
{
printf("%ld",GetLastError());
MessageBox(NULL, "La géométrie du disque (têtes, cylindres, etc..)
est impossible à obtenir.", "Erreur de lecture", MB_ICONEXCLAMATION);
return (FALSE);
}


resultat = ReadFile(cdrom, &buffer, 253, &truc2, NULL);

if(resultat)
{
printf("%ld bytes lus", truc2);
}
else
{
printf("Erreur %ld", GetLastError());
}

CloseHandle(cdrom);
return 0;
}

10 réponses

1 2 3 4
Avatar
Christian ASTOR
Yoshito wrote:

Je cherche à lire les secteurs d'un CD



La KB138434 marche très bien chez moi (XP SP2)...
Avatar
Yoshito
Ah effectivement, j'essaie merci.

Par contre apparement, la manoeuvre se fait en mode cooked. Ne sachant pas
ce que c'est, je suis allé voir sur wikipédia
(http://en.wikipedia.org/wiki/Cooked_mode) et je dois avouer que je comprend
mal ce mode mais surtout je vois que le mode alternatif est le mode raw (ce
que je voulais faire à la base).

Est-ce que le mode cooked me permettra quand meme de récupérer la valeur
exacte imprimée sur le cd sur chaque secteur ?

"Christian ASTOR" a écrit dans le message de
news:493ab7e6$1$28677$
Yoshito wrote:

Je cherche à lire les secteurs d'un CD



La KB138434 marche très bien chez moi (XP SP2)...


Avatar
Christian ASTOR
Yoshito wrote:

Par contre apparement, la manoeuvre se fait en mode cooked. Ne sachant
pas ce que c'est, je suis allé voir sur wikipédia
(http://en.wikipedia.org/wiki/Cooked_mode) et je dois avouer que je
comprend mal ce mode mais surtout je vois que le mode alternatif est le
mode raw (ce que je voulais faire à la base).

Est-ce que le mode cooked me permettra quand meme de récupérer la valeur
exacte imprimée sur le cd sur chaque secteur ?



Oui, si on lance l'exemple, on obtient bien la signature CD001 sur le
secteur 16 et les mêmes données qu'avec un éditeur Hexa comme Hex Workshop
Avatar
Yoshito
Merci, cela marche.

J'ai par contre un autre problème dont je ne comprend pas l'origine, j'ai
fait une boucle avec la fonction ReadFile dedans, au premier de boucle,
aucun problèmes (on entend bien le CD tourner et remplir le buffer) et dès
le 2eme tour, on sent le CD qui ne veut plus tourner et ça fini par une
erreur O/I du périph.

A quoi celà est-il due ? Faut-il laisser un temps d'arrêts entre la lecture
de 2 blocs ?


"Christian ASTOR" a écrit dans le message de
news:493bae93$0$28676$
Yoshito wrote:

Par contre apparement, la manoeuvre se fait en mode cooked. Ne sachant
pas ce que c'est, je suis allé voir sur wikipédia
(http://en.wikipedia.org/wiki/Cooked_mode) et je dois avouer que je
comprend mal ce mode mais surtout je vois que le mode alternatif est le
mode raw (ce que je voulais faire à la base).

Est-ce que le mode cooked me permettra quand meme de récupérer la valeur
exacte imprimée sur le cd sur chaque secteur ?



Oui, si on lance l'exemple, on obtient bien la signature CD001 sur le
secteur 16 et les mêmes données qu'avec un éditeur Hexa comme Hex Workshop


Avatar
Yoshito
Je viens de faire la technique.
Je recupère les infos par paquets de 1mo, au premier méga ça va mais dès le
deuxième le lecteur semble ne plus vouloir tourner, la diode d'occupation
reste longtemps allumée sans que le cd tourne puis ca finit par une erreur
I/O de périph :(

Pourquoi ? J'utilise mal la fonction ??

"Christian ASTOR" a écrit dans le message de
news:493bae93$0$28676$
Yoshito wrote:

Par contre apparement, la manoeuvre se fait en mode cooked. Ne sachant
pas ce que c'est, je suis allé voir sur wikipédia
(http://en.wikipedia.org/wiki/Cooked_mode) et je dois avouer que je
comprend mal ce mode mais surtout je vois que le mode alternatif est le
mode raw (ce que je voulais faire à la base).

Est-ce que le mode cooked me permettra quand meme de récupérer la valeur
exacte imprimée sur le cd sur chaque secteur ?



Oui, si on lance l'exemple, on obtient bien la signature CD001 sur le
secteur 16 et les mêmes données qu'avec un éditeur Hexa comme Hex Workshop


Avatar
Fred
Yoshito wrote:
Je viens de faire la technique.
Je recupère les infos par paquets de 1mo, au premier méga ça va mais dès
le deuxième le lecteur semble ne plus vouloir tourner, la diode
d'occupation reste longtemps allumée sans que le cd tourne puis ca finit
par une erreur I/O de périph :(

Pourquoi ? J'utilise mal la fonction ??



tu as dû te planter dans ton code.
j'ai modifié l'exemple pour lire des centaines de secteurs et ça marche
sans problème.
Avatar
Yoshito
Ah bon ?

Voici le code pourtant qui est presque comme l'exemple :

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winioctl.h>

#define CD "\.h:"
#define url "CD.cdc"

void GoOut();

int main()
{
long BLOC = 1048576;
HANDLE cdrom, fichierCDC;
BOOL resultat, ecriture;
DWORD truc, octetsLus = 0, octetsEcrits = 0;
DISK_GEOMETRY buff;
char* buffer; // Buffer : 1 Mo 1048576
long nbALire = BLOC;
unsigned long distanceBase = 0;
unsigned long int distance = 0;
int i=0, j=0;


cdrom = CreateFile(CD, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
fichierCDC = CreateFile(url, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);

if(cdrom == INVALID_HANDLE_VALUE) // cannot open the drive
{
printf("Le lecteur que vous avez indiqué est impossible à ouvrir
pour une raison absolument inconnue :pnVous avez sans doute mal tapé la
lettre du lecteur.");
GoOut(0);
}

if(fichierCDC == INVALID_HANDLE_VALUE)
{
printf("Impossible de créer le fichier.n");
GoOut(1);
}

resultat = DeviceIoControl(cdrom, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL,
0, &buff, sizeof(buff), &truc, NULL);

if(resultat)
{
printf("- Cylindres = %ldn", buff.Cylinders);
printf("- Pistes/Cylindres = %ldn", (ULONG)
buff.TracksPerCylinder);
printf("- Secteurs/Pistes = %ldn", (ULONG) buff.SectorsPerTrack);
printf("- Octets/Secteurs = %ldn", (ULONG) buff.BytesPerSector);
printf("n");
}
else
{
printf("%ld",GetLastError());
printf("La géométrie du disque (têtes, cylindres, etc..) est
impossible à obtenir.");
GoOut(2);
}

SetFilePointer(cdrom, distanceBase, NULL, FILE_BEGIN);

for(j=0; j<10; j++)
{
printf("Bloc n°%ld: ",j);

buffer = malloc(sizeof(char)*BLOC + 1);
resultat = ReadFile(cdrom, buffer, BLOC, &octetsLus, NULL);

if(resultat)
{
printf("%ld bytes lus - ", octetsLus);
ecriture = WriteFile(fichierCDC, buffer, BLOC, &octetsEcrits,
NULL);

if(ecriture)
{
if(octetsEcrits == octetsLus)
{
printf("%ld octets écrits", octetsEcrits);
}
else
{
printf("Erreur d'écriture : %ld ecrits, %ld
lus",octetsEcrits,octetsLus);
GoOut(3);
}
}
else
{
printf("Impossible d'écrire sur le fichier.");
GoOut(4);
}
printf("n");
}
else
{
GoOut(5);
}

free(buffer);
/*distance = distance + BLOC;
SetFilePointer(cdrom, distance, NULL, FILE_CURRENT);*/
Sleep(15000);
}

CloseHandle(cdrom);
return 0;
}


void GoOut(int x)
{
printf("nOperation %ld : Erreur %ldn", x, GetLastError());
system("pause");
exit(-1);
}
Avatar
Fred
Yoshito wrote:
Ah bon ?

Voici le code pourtant qui est presque comme l'exemple :




euh, presque ? ce n'est pas vraiment le même code
BytesPerSector n'est pas pris en compte par exemple
il faut toujours repartir des exemples de Microsoft et les modifier
Avatar
Yoshito
Je suis donc repartit d'un exemple de microsoft pour le modifier.

Je fais une boucle qui récupère 1000 blocs de 10 secteurs d'un coups.
Pendant les 85 premiers tours aucuns problèmes mais ensuite le lecteur se
bloque (pendant une cinquantaine de seconde ensuite il refait un tour puis
se rebloque, etc...) et quand je change la taille du buffer, exactement
pareil.
Comme si le lecteur empechait de récupérer + de quelques mégas d'un coup.

Voici le code, dites moi avis d'experts :

#include <windows.h>
#include <winioctl.h> // From the Win32 SDK MstoolsInclude
#include "ntddcdrm.h" // From the Windows NT DDK DdkSrcStorageInc

#define EMPLACEMENT_FICHIER_CDC "coco.txt"
#define EMPLACEMENT_CDROM "\.h:"

void goOut(int x, char* msg);

int main()
{
HANDLE cdrom, fichierCDC;
DWORD dwNotUsed;
BOOL resultat;
DISK_GEOMETRY dgCDROM;
PREVENT_MEDIA_REMOVAL pmrLockCDROM;
LPBYTE lpSector;
DWORD dwSize;
int i=0;

// Disk file that will hold the CD-ROM sector data.
fichierCDC = CreateFile (EMPLACEMENT_FICHIER_CDC,GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);

if(fichierCDC == INVALID_HANDLE_VALUE)
{
goOut(1, "Fichier CDC impossible à créer.");
}


// For the purposes of this sample, drive F: is the CD-ROM
// drive.
cdrom = CreateFile (EMPLACEMENT_CDROM,
GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);

if(cdrom == INVALID_HANDLE_VALUE)
{
goOut(2, "Impossible de charger le CD.");
}

// Lock the compact disc in the CD-ROM drive to prevent accidental
// removal while reading from it.
pmrLockCDROM.PreventMediaRemoval = FALSE;
resultat = DeviceIoControl (cdrom, IOCTL_CDROM_MEDIA_REMOVAL,
&pmrLockCDROM, sizeof(pmrLockCDROM), NULL,0, &dwNotUsed, NULL);

if(!resultat)
{
goOut(3, "Impossible de protéger le CD.");
}

// Get sector size of compact disc
resultat = DeviceIoControl(cdrom, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL,
0, &dgCDROM, sizeof(dgCDROM),&dwNotUsed, NULL);

if(!resultat)
{
goOut(4, "Impossible d'obtenir la géométrie du disque.");
}

printf("- Cylindres = %ldn", dgCDROM.Cylinders);
printf("- Pistes/Cylindres = %ldn", (ULONG) dgCDROM.TracksPerCylinder);
printf("- Secteurs/Pistes = %ldn", (ULONG) dgCDROM.SectorsPerTrack);
printf("- Octets/Secteurs = %ldn", (ULONG) dgCDROM.BytesPerSector);
printf("n");

dwSize = 10 * dgCDROM.BytesPerSector;

// Allocate buffer to hold sectors from compact disc. Note that
// the buffer will be allocated on a sector boundary because the
// allocation granularity is larger than the size of a sector on a
// compact disk.


SetFilePointer (cdrom, 0,NULL, FILE_BEGIN);


for(i=0;i<1000;i++)
{
lpSector = VirtualAlloc (NULL,
dwSize,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
printf("Bloc %ldn",i);
if (ReadFile (cdrom, lpSector, dwSize, &dwNotUsed, NULL))
WriteFile (fichierCDC, lpSector, dwSize, &dwNotUsed, NULL);

VirtualFree (lpSector, 0, MEM_RELEASE);
}

// Unlock the disc in the CD-ROM drive.
pmrLockCDROM.PreventMediaRemoval = FALSE;
DeviceIoControl (cdrom, IOCTL_CDROM_MEDIA_REMOVAL,&pmrLockCDROM,
sizeof(pmrLockCDROM), NULL,0, &dwNotUsed, NULL);

CloseHandle (cdrom);
CloseHandle (fichierCDC);

return 0;
}

void goOut(int x, char* msg)
{
printf("n");
printf("%sn", msg);
printf("Operation %ld : Erreur %ldn", x, GetLastError());
system("pause");
exit(-1);
}
Avatar
jean
"Yoshito" wrote in message
news:ghpbfj$8eg$
Je suis donc repartit d'un exemple de microsoft pour le modifier.

Je fais une boucle qui récupère 1000 blocs de 10 secteurs d'un coups.
Pendant les 85 premiers tours aucuns problèmes mais ensuite le lecteur se
bloque (pendant une cinquantaine de seconde ensuite il refait un tour puis
se rebloque, etc...) et quand je change la taille du buffer, exactement
pareil.
Comme si le lecteur empechait de récupérer + de quelques mégas d'un coup.



Ton CD doit avoir une particularité ou un problème.
Je viens de tester avec plusieurs CD de données ou même des DVD, ça passe
sans problème...
1 2 3 4