RESPUESTA A LA PREGUNTA NUMERO 540 Seguramente quien pregunta quiere evitar que una copia de su aplicación funcione fácilmente en otro disco. Aunque SYS(2020) y SYS(2022) puede ayudar un poco a este propósito, por si solos no evitará que la aplicación funcione en discos de geometría igual. Con ENSAMBLADOR leyendo el sector 0 del disco o diskette se encuentra los 4 bytes del serial a partir de la posición 39 (Fat12) o 67(Fat 32). Debo confesar que no tuve mucha suerte usando FOXPRO 2.5 y una librería con una rutina en ASSEMBLER. La computadora se tornaba muy inestable colgándose por alguno de esos misterios del "Modo Protegido". Así que después de una frustrante lucha con el DEBUGER decidí bajarme de Rocinante, convertime en Sancho y hacer el siguiente programa que utiliza el resultado del comando VOL del DOS. *- cDskSerial.prg *- Decio 19/3/95 LPARAMETER tcDrive IF EMPTY(tcDrive) RETURN '' ENDIF LOCAL lcFileName, lnFile, lcLinea, lcDskSerial lcFileName = SYS(3) + ".TMP" && Nombre del archivo temporal para !VOL &tcDrive > &lcFileName && guardar el resultado del comando VOL de DOS. lnFile = FOPEN(lcFilename) && Abrir el archivo de texto creado IF lnFile = -1 && y burcar el Serial del Disco. ? CHR(7) WAIT "Error. No se puede verificar seriales." WINDOW RETURN ELSE DO WHILE NOT FEOF(lnFile) lcLinea= UPPER(TRIM(FGETS(lnFile))) DO CASE CASE "SERIAL NUMBER" $ lcLinea && Cuidado con otro idioma del S.O. lcDskSerial = RIGHT(lcLinea,9) CASE "SERIE DEL VOLUMEN" $ lcLinea lcDskSerial = RIGHT(lcLinea,9) ENDCASE ENDDO =FCLOSE(lnFile) ERASE (lcFileName) ENDIF RETURN lcDskSerial No es elegante pero la máquina de mi cliente dejo de 'guindarse'... Al menos tiene el mérito de servir de ejercicio sobre comandos de bajo nivel para el manejo de archivos. Bajo Window existe una mejor solución que evita problemas con nuevas versiones del S.O. La siguiente es una rutina para VFP: * nVolInf.prg * Decio 10/11/98 LPARAMETER lpRootPathName && Directorio raiz del disco que se desea información. IF PARAMETERS() < 1 lpRootPathName = SET('DEFAULT') + '\' ENDIF lpVolumeNameBuffer = '' nVolumeNameSize = 0 lpVolumeSerialNumber = 0 lpMaximumComponentLength = 0 lpFileSystemFlags = 0 lpFileSystemNameBuffer = '' nFileSystemNameSize = 0 DECLARE LONG GetVolumeInformation IN kernel32 ; String lpRootPathName, ; String lpVolumeNameBuffer, ; Long nVolumeNameSize , ; Long @ lpVolumeSerialNumber, ; Long @ lpMaximumComponentLength, ; Long @ lpFileSystemFlags, ; String lpFileSystemNameBuffer, ; Long nFileSystemNameSize = GetVolumeInformation(lpRootPathName, ; lpVolumeNameBuffer,; nVolumeNameSize, ; @lpVolumeSerialNumber, ; @lpMaximumComponentLength, ; @lpFileSystemFlags, ; lpFileSystemNameBuffer, ; nFileSystemNameSize) *- Mostrar ? ' Serial del disco:', lpVolumeSerialNumber ** El significado de los demás parámetros lo dejo a vuestra curiosidad proactiva. Una combinación de los comandos SYS mencionados con esta rutina y una de encriptación hará algo difícil (no imposible) que una copia de su aplicación funcione en otro disco. Decio Rodríguez deciorf@cantv.net