Newsgroup: it.comp.programmare.win32
Titolo: Problema: Numero seriale dei dischi fissi e CD-ROM

Salve,
ho un problema. Sto scrivendo un programma che:
-enumera tutti i cd-rom presenti sul sistema e
-poi li prende uno per uno e ne cerca il numero seriale
Ho implementato una funzione a riguardo che usa GetVolumeInformation,
dabdo come primo parametro la lettera del CD-ROM(ad. es. D:). Ma, guarda
qua, non funziona. GetVolumeInformation returna 0, poi vado a
controllare con GetLastError. Questo mi dá 83, INVALID_ARGUMENTS o via
di lí. Il seriale non viene scritto nella variable, come del resto tutti
gli altri valori.
Vi posto il codice, spero mi possiate aiutare.
//inizio funzione GetSerial()
{
UpdateData(true);
  char lpVolumeNameBuffer;
  unsigned long lpVolumeSerialNumber;
  LPDWORD lpMaximumComponentLength;
  LPDWORD lpFileSystemFlags;
  LPTSTR lpFileSystemNameBuffer;
    bool ok; //verifica corretto funzionamento
  ok =
GetVolumeInformation(m_Laufwerk,&lpVolumeNameBuffer,sizeof(lpVolumeNameBuffer),
&lpVolumeSerialNumber,lpMaximumComponentLength,lpFileSystemFlags,lpFileSystemNameBuffer,
   sizeof(lpFileSystemNameBuffer));
//
m_serial = lpVolumeSerialNumber;//dai serialnumber a edit (long)
UpdateData(false)
}
//fine
Lukas Demetz

 restituire la funzione !



disks :((
Resta il fatto che la struttura dei dati in un CD-ROM e' assolutamente
diversa da quella degli HD e quindi non credo proprio che i risultati
siano corretti.
Se poi affermi che GetVolumeInformation non ti funziona neanche con
gli HD vuol dire che sbagli a passare dei parametri.
In particolare, ho visto una cosa che mi ha fatto venire la pelle
d'oca ;) :
 char lpVolumeNameBuffer ;
 ...
GetVolumeInformation(m_Laufwerk,&lpVolumeNameBuffer,sizeof(lpVolumeNameBuffer),
                      char lpVolumeNameBuffer )
Non va bene.
lpVolumeNameBuffer deve essere un vettore di caratteri, non un
carattere solo.

   LPTSTR lpFileSystemNameBuffer;
e qui cominciano i dolori:
definendo una variabile di tipo LPDWORD, viene allocato spazio in memoria
(in questo caso modificando lo stack pointer) per un puntatore ad una DWORD,
ma non per la DWORD stessa; lo stesso vale per la seguente LPTSTR: vengono
allocati 4 bytes per il puntatore al buffer, ma niente di più per il buffer
stesso.
Ecco un approccio corretto:
LPTSTR tszVolumeNameBuffer;   /*  puntatore, ma ancora niente buffer  */
DWORD dwVolumeSerialNumber;   /*  spazio effettivo   */
DWORD dwMaximumComponentLength;
DWORD dwFileSystemFlags;
LPTSTR tszFileSystemNameBuffer;   /*  puntatore, ma ancora niente buffer  */
/* Allocazione dei buffer  */
tszVolumeNameBuffer = new TCHAR[MAX_VNB];
tszFileSystemNameBuffer = new TCHAR[MAX_SNB];
/*   Chiamata corretta, supponendo che "m_Laufwerk" sia corretta; nota
l'operatore & applicato alle DWORD  */
GetVolumeInformation(m_Laufwerk,tszVolumeNameBuffer,MAX_VNB,
      &dwVolumeSerialNumber,&dwMaximumComponentLength,
      &dwFileSystemFlags,tszFileSystemNameBuffer,MAX_SNB);
m_serial = dwVolumeSerialNumber;
/*  Quando i due buffer non ti servono più   */
delete tszVolumeNameBuffer;
delete tszFileSystemNameBuffer;
Visto che a te sembra interessare solo il numero di serie, un'alternativa
potrebbe essere:
DWORD dwVolumeSerialNumber;
GetVolumeInformation(m_Laufwerk,NULL,0,&dwVolumeSerialNumber,
     NULL,NULL,NULL,0);
E' importante capire che quelle LPDWORD che definivi non vengono
automaticamente inizializzate a 0 (NULL); questo significa che la funzione
non riceve l'implicito messaggio "Ignora queste informazioni", riceve bensì
un puntatore (diverso da NULL) a una DWORD che non è stata allocata. Inoltre
c'è da dire che GetVolumeInformation è piuttosto intelligente (con il tuo
approccio, in generale, rischi la violazione d'accesso).
Stefano.