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
toutledos
On 12 déc, 21:02, "jean" wrote:
"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 coup s.
> Pendant les 85 premiers tours aucuns problèmes mais ensuite le lecteu r se
> bloque (pendant une cinquantaine de seconde ensuite il refait un tour p uis
> 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...



Ca fait un moment que j'essaie de répondre mais manifestement le
serveur de news a eu un probleme.

Bref, effectivement le CD était endommagé, car avec d'autres CD, ça
marche !

Maintenant je désirerais faire la manip en sens inverse : données ->
CD tout en réécrivant secteur par secteur.

J'ai essayé un writefile sur un CD vierge et manifestement le CD
semble se graver a une vitesse correcte (1-2X) mais une fois terminé,
dans le poste de travail il est toujours indiqué CD vierge !

Comment faire ?

Merci ;)
Avatar
Vincent Burel
Pour graver un CD, je pense qu'il faut obligatoirement passer par une
librairie spécialisé.
par exemple avec la CDMAPI (c'est du COM, IID_IDiscMaster).

VB

wrote in message
news:
On 12 déc, 21:02, "jean" wrote:
"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...



Ca fait un moment que j'essaie de répondre mais manifestement le
serveur de news a eu un probleme.

Bref, effectivement le CD était endommagé, car avec d'autres CD, ça
marche !

Maintenant je désirerais faire la manip en sens inverse : données ->
CD tout en réécrivant secteur par secteur.

J'ai essayé un writefile sur un CD vierge et manifestement le CD
semble se graver a une vitesse correcte (1-2X) mais une fois terminé,
dans le poste de travail il est toujours indiqué CD vierge !

Comment faire ?
Avatar
Christian ASTOR
Vincent Burel wrote:

Pour graver un CD, je pense qu'il faut obligatoirement passer par une
librairie spécialisé.
par exemple avec la CDMAPI (c'est du COM, IID_IDiscMaster).



Oui, avec IDiscMaster::RecordDisc()
(ou par SCSI, mais très complexe...)

Un vieil example IMAPI de MS, par fichiers (non-testé) =>

#include "stdafx.h"

#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <objbase.h>
#include <stdio.h>
#include <shlobj.h>
#include "imapi.h"

HRESULT GetStorage(LPWSTR pszDir, IStorage **ppstg)
{
IShellFolder *psfDesktop;
HRESULT hr = SHGetDesktopFolder(&psfDesktop);
if (SUCCEEDED(hr))
{
IMalloc *pm;
hr = SHGetMalloc(&pm);
if (SUCCEEDED(hr))
{
LPITEMIDLIST pidl;
hr = psfDesktop->ParseDisplayName(NULL, NULL, pszDir,
NULL,&pidl,NULL);
if (SUCCEEDED(hr))
{
hr = psfDesktop->BindToObject(pidl, NULL,
IID_IStorage,(void**)ppstg);
pm->Free(pidl);
}
pm->Release();
}
psfDesktop->Release();
}
return hr;

}

HRESULT SetUpRecorder(IDiscMaster *pdm, IJolietDiscMaster *pjdm, LPWSTR
pszDir) {
wprintf(L"Getting recorder enumerator object.n");

IEnumDiscRecorders *pedr;
HRESULT hr = pdm->EnumDiscRecorders(&pedr);
if (SUCCEEDED(hr))
{
wprintf(L"Finding available drive.n");

ULONG celt;
IDiscRecorder *pdr;
// pick the first supported drive to write to.
hr = pedr->Next(1, &pdr, &celt);
if (S_OK == hr)
{
wprintf(L"Setting active disc recorder.n");

hr = pdm->SetActiveDiscRecorder(pdr);
if (SUCCEEDED(hr))
{
IStorage *pstg;
hr = GetStorage(pszDir, &pstg);
if (SUCCEEDED(hr))
{
wprintf(L"Adding data to stash file.n");
hr = pjdm->AddData(pstg, 1);
pstg->Release();
}
else
{
wprintf(L"Couldn't get storage, please check
thepath.n");
}
}
pdr->Release();
}
else
{
wprintf(L"No supported drives found, HRESULT = 0x%08Xn", hr);
hr = E_FAIL;
}
pedr->Release();
}
return hr;

}

void DoBurn(LPWSTR pszDir)
{
wprintf(L"Burning directory %s.n", pszDir);

wprintf(L"CoCreating object.n");
IDiscMaster *pdm;
HRESULT hr = CoCreateInstance(CLSID_MSDiscMasterObj, NULL,
CLSCTX_ALL,IID_IDiscMaster, (void**)&pdm);
if (SUCCEEDED(hr))
{
wprintf(L"Initializing.n");

hr = pdm->Open();
if (SUCCEEDED(hr))
{
wprintf(L"Setting active disc master format to Joliet.n");

IJolietDiscMaster *pjdm;
hr =
pdm->SetActiveDiscMasterFormat(IID_IJolietDiscMaster,(void**)&pjdm);
if (SUCCEEDED(hr))
{
hr = SetUpRecorder(pdm, pjdm, pszDir);
if (SUCCEEDED(hr))
{
wprintf(L"Burning disc.n");
// first param FALSE for non-simulated burn.
// second param TRUE to eject on completion.
hr = pdm->RecordDisc(FALSE, TRUE);
}
// Get IDiscRecorder and close;
IDiscRecorder* piDR;
pdm->GetActiveDiscRecorder(&piDR);
piDR->Close();

pjdm->Release();
}
}
pdm->Release();
}

if (SUCCEEDED(hr))
{
wprintf(L"Burning succeeded.n");
}
else
{
wprintf(L"Failure, HRESULT = 0x%08Xn", hr);
}

}

int __cdecl wmain(int argc, WCHAR *argv[])
{
if (argc != 2)
{
wprintf(L"IMAPI demonUsage: %s <directory to burn>nExample:
"%sc:files"n", argv[0], argv[0]);
}
else
{
if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)))
{
DoBurn(argv[1]);

//================================================================== //detect if the burn operation worked:
WIN32_FIND_DATA data;
HRESULT hr;
HANDLE hFind = FindFirstFile((LPCTSTR)"e:CDBurn.exe", &data);
if (hFind == INVALID_HANDLE_VALUE)
{
printf("RecordDisc did not return error but no files were burned");
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); //<====it
alwayscomeshere
}
else
{
FindClose(hFind);
hr = S_OK;
} //================================================================== CoUninitialize();
}
}
return 0;
Avatar
toutledos
Merci.

Pour en revenir à les lectures des secteurs, je viens de trouver un
article sur le net, et le code que j'utilise extrait bien des secteurs
de 2048 octets.

Or ce ne sont pas les octets originaux, il semble qu'il y ait d'abord
une correction d'erreurs ainsi que quelques autres opérations.
Je désirerais avoir EXACTEMENT (donc au bit près) les même données que
le CD malgré les erreurs présentes.

D'après la MSDN j'utilise le mode cooked dans mon code et pour faire
ce que je voudrais faire il faudrait que j'utilise le mode Raw.
Quelqu'un peut confirmer ou m'expliquer ?

merci
Avatar
Michael
wrote in message
news:

Or ce ne sont pas les octets originaux, il semble qu'il y ait d'abord
une correction d'erreurs ainsi que quelques autres opérations.
Je désirerais avoir EXACTEMENT (donc au bit près) les même données que
le CD malgré les erreurs présentes.



Ca doit bien être les octets originaux.
Il te suffit de comparer avec un Editeur de Secteur/Disque, tu dois obtenir
la même chose.
Avatar
toutledos
C'est bon, j'ai trouvé la technique pour lire les 2352 octets par
blocs.

Sinon pour l'exemple avec IMAPI j'ai un problème, pour avoir la
fonction qui copie secteur/secteur c'est dans l'IMAPI v2, or ici c'est
la v1.

Il faudrait donc initialiser la v2 plutot que la v1 or je n'ai pas
trouvé comment faire.
Je pense que c'est cette ligne :
CoCreateInstance(CLSID_MSDiscMasterObj, NULL,
CLSCTX_ALL,IID_IDiscMaster, (void**)&pdm);
qu'il faut changer. Comment faire ?
Avatar
Michael
wrote in message
news:

Il faudrait donc initialiser la v2 plutot que la v1 or je n'ai pas
trouvé comment faire.
Je pense que c'est cette ligne :
CoCreateInstance(CLSID_MSDiscMasterObj, NULL,
CLSCTX_ALL,IID_IDiscMaster, (void**)&pdm);
qu'il faut changer. Comment faire ?



Tu choisis juste l'interface que tu veux utiliser.
genre IDiscMaster2 et les bons uuid pour le CoCreateInstance, comme écrit
dans la doc Msdn.
Avatar
toutledos
C'est bien ce que j'ai fait :

IWriteEngine2 *pdm;
CoCreateInstance(__uuidof(MsftWriteEngine2), NULL,
CLSCTX_ALL,__uuidofIWriteEngine2), (void**)&pdm)

Mais voila les erreurs que j'avais :
1>c:usersflorentdocumentsvisual studio 2008projects
test3test3main.c(364) : error C2065: 'IWriteEngine2' :
identificateur non déclaré
1>c:usersflorentdocumentsvisual studio 2008projects
test3test3main.c(364) : error C2065: 'pdm' : identificateur non
déclaré
1>c:usersflorentdocumentsvisual studio 2008projects
test3test3main.c(372) : error C2065: 'MsftWriteEngine2' :
identificateur non déclaré
1>c:usersflorentdocumentsvisual studio 2008projects
test3test3main.c(372) : error C2065: 'IWriteEngine2' :
identificateur non déclaré
1>c:usersflorentdocumentsvisual studio 2008projects
test3test3main.c(372) : error C2065: 'pdm' : identificateur non
déclaré

Pourtant j'ai gardé les mêmes headers que dans l'exemple !
Avatar
Christian ASTOR
wrote:
C'est bien ce que j'ai fait :

IWriteEngine2 *pdm;



Pourtant j'ai gardé les mêmes headers que dans l'exemple !



Ben justement, il faut changer si c'est IMAPI 2

#include <imapi2.h>
Avatar
toutledos
On 28 déc, 20:32, Christian ASTOR wrote:
wrote:
> C'est bien ce que j'ai fait :

> IWriteEngine2 *pdm;
> Pourtant j'ai gardé les mêmes headers que dans l'exemple !

Ben justement, il faut changer si c'est IMAPI 2

#include <imapi2.h>



D'accord c'est fait, j'avance à petit pas.

J'ai encore un problème : je ne trouve pas la fonction qui permet de
selectionner le lecteur que l'on veut, j'ai trouvé par contre celle
qui permet de les énumérer.
Comment faire ?
1 2 3 4