2011-12-19 9 views
7

Estoy tratando de desmontar un volumen en mi aplicación Cocoa utilizando el Marco de Arbitraje de Discos.Interpretar el valor de retorno (disidente) al intentar desmontar el volumen en OS X

Antes de llamar:

DADiskUnmount(disk, 
       kDADiskUnmountOptionDefault, 
       unmountCallback, 
       self); 

que registra una función de devolución de llamada que consiguen que se llama después:

void unmountCallback(DADiskRef disk, DADissenterRef dissenter, void *context) 
{ 
    if (dissenter != NULL) 
    { 
     DAReturn ret = DADissenterGetStatus(dissenter); 

     switch (ret) { 
     case kDAReturnBusy: 
      printf("kDAReturnBusy\n"); 
      break; 
    } 
} 

En esta función trato de interpretar el valor de retorno disidente pero queda bloqueado. Supongo que debería ser de tipo DAReturn y tener un valor como kDAReturnBusy Pero cuando, por ejemplo, iTunes está usando el volumen y no se puede desmontar. "ret" tiene un valor de 0xc010 que no entiendo del todo.

En caso de que falle el desmontaje, me gustaría saber por qué el volumen no se puede desmontar y, en caso de que otra aplicación lo esté utilizando, recuerde al usuario que debe cerrar esta aplicación.

Respuesta

16

Pero cuando, por ejemplo, iTunes está usando el volumen y no se puede desmontar. "ret" tiene un valor de 0xc010 que no entiendo del todo.

La documentación se ha vinculado a, para el tipo DAReturn, enumera todas las constantes de Arbitraje de disco como parecido a esto:

kDAReturnError = err_local | err_local_diskarbitration | 0x01, /* (0xF8DA0001) */ 

Así, devuelve un error de DA están hechos de tres componentes , O juntos.

Si nos fijamos en the documentation for DADissenterGetStatus, que dice:

Un código de retorno BSD, en su caso, se codifica con unix_err().

Si a continuación, buscar las cabeceras de unix_err, lo encuentras en /usr/include/mach/error.h, que dice:

/* unix errors get lumped into one subsystem */ 
#define unix_err(errno)  (err_kern|err_sub(3)|errno) 

y:

/* 
* error number layout as follows: 
* 
* hi      lo 
* | system(6) | subsystem(12) | code(14) | 
*/ 

Hay esos tres com ponents de nuevo. Algunas otras macros en error.h organizan los valores de sistema y subsistema (por ejemplo, err_kern y err_sub(3)) en esas posiciones.

Así que ahora, vamos a abrir la calculadora, pulse ⌘3 ponerlo en modo de programador, cambiar a base 16, y teclee el código de error, y ver lo que dice:

0xC010

0000 0000 0000 0000 1100 0000 0001 0000 
31     15    0 

Rompiendo que aparte según la disposición anterior, encontramos:

0000 00 
31  

Sistema: 0, que error.h dice es err_kern. Este error vino del kernel.

 00 0000 0000 11 
31     15 

Subsystem: 3 (0b11). Esto más el código del sistema coincide con la definición antes mencionada de unix_err. Entonces este es un código de retorno BSD, como dijo DADissenterGetStatus.

     00 0000 0001 0000 
31     15    0 

código de error individual: 16 (0x10, 0b10000).

errores UNIX/BSD se definen en <sys/errno.h>, que dice:

#define EBUSY  16  /* Device/Resource busy */ 

Esto me sugiere que no se puede desmontar el dispositivo porque está en uso.

+1

(Me gustaría darle puntos extra para el tutorial detallado que cada nuevo sistema debería ver en algún momento). –

+1

@quixoto no dude en ofrecer una recompensa por la pregunta y luego entréguela a Peter :) –

+0

Gracias muchísimo, Peter por tu respuesta completa. ¡Esta es exactamente la información que estaba buscando! – JLinX

Cuestiones relacionadas