1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 /* 25 * Conversion parameters: 26 * inFile = GDrive.html 27 * outPack = gio 28 * outFile = DriveT 29 * strct = GDrive 30 * realStrct= 31 * ctorStrct= 32 * clss = DriveT 33 * interf = DriveIF 34 * class Code: No 35 * interface Code: No 36 * template for: 37 * - TStruct 38 * extend = 39 * implements: 40 * prefixes: 41 * - g_drive_ 42 * omit structs: 43 * omit prefixes: 44 * omit code: 45 * omit signals: 46 * imports: 47 * - glib.Str 48 * - glib.ErrorG 49 * - glib.GException 50 * - glib.ListG 51 * - gobject.Signals 52 * - gio.AsyncResultIF 53 * - gio.Cancellable 54 * - gio.Icon 55 * - gio.IconIF 56 * - gio.MountOperation 57 * structWrap: 58 * - GAsyncResult* -> AsyncResultIF 59 * - GCancellable* -> Cancellable 60 * - GIcon* -> IconIF 61 * - GList* -> ListG 62 * - GMountOperation* -> MountOperation 63 * module aliases: 64 * local aliases: 65 * overrides: 66 */ 67 68 module gio.DriveT; 69 70 public import gtkc.giotypes; 71 72 public import gtkc.gio; 73 public import glib.ConstructionException; 74 public import gobject.ObjectG; 75 76 public import gobject.Signals; 77 public import gtkc.gdktypes; 78 public import glib.Str; 79 public import glib.ErrorG; 80 public import glib.GException; 81 public import glib.ListG; 82 public import gobject.Signals; 83 public import gio.AsyncResultIF; 84 public import gio.Cancellable; 85 public import gio.Icon; 86 public import gio.IconIF; 87 public import gio.MountOperation; 88 89 90 91 /** 92 * GDrive - this represent a piece of hardware connected to the machine. 93 * It's generally only created for removable hardware or hardware with 94 * removable media. 95 * 96 * GDrive is a container class for GVolume objects that stem from 97 * the same piece of media. As such, GDrive abstracts a drive with 98 * (or without) removable media and provides operations for querying 99 * whether media is available, determining whether media change is 100 * automatically detected and ejecting the media. 101 * 102 * If the GDrive reports that media isn't automatically detected, one 103 * can poll for media; typically one should not do this periodically 104 * as a poll for media operation is potententially expensive and may 105 * spin up the drive creating noise. 106 * 107 * GDrive supports starting and stopping drives with authentication 108 * support for the former. This can be used to support a diverse set 109 * of use cases including connecting/disconnecting iSCSI devices, 110 * powering down external disk enclosures and starting/stopping 111 * multi-disk devices such as RAID devices. Note that the actual 112 * semantics and side-effects of starting/stopping a GDrive may vary 113 * according to implementation. To choose the correct verbs in e.g. a 114 * file manager, use g_drive_get_start_stop_type(). 115 * 116 * For porting from GnomeVFS note that there is no equivalent of 117 * GDrive in that API. 118 */ 119 public template DriveT(TStruct) 120 { 121 122 /** the main Gtk struct */ 123 protected GDrive* gDrive; 124 125 126 /** Get the main Gtk struct */ 127 public GDrive* getDriveTStruct() 128 { 129 return cast(GDrive*)getStruct(); 130 } 131 132 133 /** 134 */ 135 int[string] connectedSignals; 136 137 void delegate(DriveIF)[] _onChangedListeners; 138 @property void delegate(DriveIF)[] onChangedListeners() 139 { 140 return _onChangedListeners; 141 } 142 /** 143 * Emitted when the drive's state has changed. 144 */ 145 void addOnChanged(void delegate(DriveIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 146 { 147 if ( !("changed" in connectedSignals) ) 148 { 149 Signals.connectData( 150 getStruct(), 151 "changed", 152 cast(GCallback)&callBackChanged, 153 cast(void*)cast(DriveIF)this, 154 null, 155 connectFlags); 156 connectedSignals["changed"] = 1; 157 } 158 _onChangedListeners ~= dlg; 159 } 160 extern(C) static void callBackChanged(GDrive* driveStruct, DriveIF _driveIF) 161 { 162 foreach ( void delegate(DriveIF) dlg ; _driveIF.onChangedListeners ) 163 { 164 dlg(_driveIF); 165 } 166 } 167 168 void delegate(DriveIF)[] _onDisconnectedListeners; 169 @property void delegate(DriveIF)[] onDisconnectedListeners() 170 { 171 return _onDisconnectedListeners; 172 } 173 /** 174 * This signal is emitted when the GDrive have been 175 * disconnected. If the recipient is holding references to the 176 * object they should release them so the object can be 177 * finalized. 178 */ 179 void addOnDisconnected(void delegate(DriveIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 180 { 181 if ( !("disconnected" in connectedSignals) ) 182 { 183 Signals.connectData( 184 getStruct(), 185 "disconnected", 186 cast(GCallback)&callBackDisconnected, 187 cast(void*)cast(DriveIF)this, 188 null, 189 connectFlags); 190 connectedSignals["disconnected"] = 1; 191 } 192 _onDisconnectedListeners ~= dlg; 193 } 194 extern(C) static void callBackDisconnected(GDrive* driveStruct, DriveIF _driveIF) 195 { 196 foreach ( void delegate(DriveIF) dlg ; _driveIF.onDisconnectedListeners ) 197 { 198 dlg(_driveIF); 199 } 200 } 201 202 void delegate(DriveIF)[] _onEjectButtonListeners; 203 @property void delegate(DriveIF)[] onEjectButtonListeners() 204 { 205 return _onEjectButtonListeners; 206 } 207 /** 208 * Emitted when the physical eject button (if any) of a drive has 209 * been pressed. 210 */ 211 void addOnEjectButton(void delegate(DriveIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 212 { 213 if ( !("eject-button" in connectedSignals) ) 214 { 215 Signals.connectData( 216 getStruct(), 217 "eject-button", 218 cast(GCallback)&callBackEjectButton, 219 cast(void*)cast(DriveIF)this, 220 null, 221 connectFlags); 222 connectedSignals["eject-button"] = 1; 223 } 224 _onEjectButtonListeners ~= dlg; 225 } 226 extern(C) static void callBackEjectButton(GDrive* driveStruct, DriveIF _driveIF) 227 { 228 foreach ( void delegate(DriveIF) dlg ; _driveIF.onEjectButtonListeners ) 229 { 230 dlg(_driveIF); 231 } 232 } 233 234 void delegate(DriveIF)[] _onStopButtonListeners; 235 @property void delegate(DriveIF)[] onStopButtonListeners() 236 { 237 return _onStopButtonListeners; 238 } 239 /** 240 * Emitted when the physical stop button (if any) of a drive has 241 * been pressed. 242 * Since 2.22 243 */ 244 void addOnStopButton(void delegate(DriveIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 245 { 246 if ( !("stop-button" in connectedSignals) ) 247 { 248 Signals.connectData( 249 getStruct(), 250 "stop-button", 251 cast(GCallback)&callBackStopButton, 252 cast(void*)cast(DriveIF)this, 253 null, 254 connectFlags); 255 connectedSignals["stop-button"] = 1; 256 } 257 _onStopButtonListeners ~= dlg; 258 } 259 extern(C) static void callBackStopButton(GDrive* driveStruct, DriveIF _driveIF) 260 { 261 foreach ( void delegate(DriveIF) dlg ; _driveIF.onStopButtonListeners ) 262 { 263 dlg(_driveIF); 264 } 265 } 266 267 268 /** 269 * Gets the name of drive. 270 * Returns: a string containing drive's name. The returned string should be freed when no longer needed. 271 */ 272 public string getName() 273 { 274 // char * g_drive_get_name (GDrive *drive); 275 return Str.toString(g_drive_get_name(getDriveTStruct())); 276 } 277 278 /** 279 * Gets the icon for drive. 280 * Returns: GIcon for the drive. Free the returned object with g_object_unref(). [transfer full] 281 */ 282 public IconIF getIcon() 283 { 284 // GIcon * g_drive_get_icon (GDrive *drive); 285 auto p = g_drive_get_icon(getDriveTStruct()); 286 287 if(p is null) 288 { 289 return null; 290 } 291 292 return ObjectG.getDObject!(Icon, IconIF)(cast(GIcon*) p); 293 } 294 295 /** 296 * Gets the icon for drive. 297 * Since 2.34 298 * Returns: symbolic GIcon for the drive. Free the returned object with g_object_unref(). [transfer full] 299 */ 300 public IconIF getSymbolicIcon() 301 { 302 // GIcon * g_drive_get_symbolic_icon (GDrive *drive); 303 auto p = g_drive_get_symbolic_icon(getDriveTStruct()); 304 305 if(p is null) 306 { 307 return null; 308 } 309 310 return ObjectG.getDObject!(Icon, IconIF)(cast(GIcon*) p); 311 } 312 313 /** 314 * Check if drive has any mountable volumes. 315 * Returns: TRUE if the drive contains volumes, FALSE otherwise. 316 */ 317 public int hasVolumes() 318 { 319 // gboolean g_drive_has_volumes (GDrive *drive); 320 return g_drive_has_volumes(getDriveTStruct()); 321 } 322 323 /** 324 * Get a list of mountable volumes for drive. 325 * The returned list should be freed with g_list_free(), after 326 * its elements have been unreffed with g_object_unref(). 327 * Returns: GList containing any GVolume objects on the given drive. [element-type GVolume][transfer full] 328 */ 329 public ListG getVolumes() 330 { 331 // GList * g_drive_get_volumes (GDrive *drive); 332 auto p = g_drive_get_volumes(getDriveTStruct()); 333 334 if(p is null) 335 { 336 return null; 337 } 338 339 return ObjectG.getDObject!(ListG)(cast(GList*) p); 340 } 341 342 /** 343 * Checks if a drive can be ejected. 344 * Returns: TRUE if the drive can be ejected, FALSE otherwise. 345 */ 346 public int canEject() 347 { 348 // gboolean g_drive_can_eject (GDrive *drive); 349 return g_drive_can_eject(getDriveTStruct()); 350 } 351 352 /** 353 * Gets a hint about how a drive can be started/stopped. 354 * Since 2.22 355 * Returns: A value from the GDriveStartStopType enumeration. 356 */ 357 public GDriveStartStopType getStartStopType() 358 { 359 // GDriveStartStopType g_drive_get_start_stop_type (GDrive *drive); 360 return g_drive_get_start_stop_type(getDriveTStruct()); 361 } 362 363 /** 364 * Checks if a drive can be started. 365 * Since 2.22 366 * Returns: TRUE if the drive can be started, FALSE otherwise. 367 */ 368 public int canStart() 369 { 370 // gboolean g_drive_can_start (GDrive *drive); 371 return g_drive_can_start(getDriveTStruct()); 372 } 373 374 /** 375 * Checks if a drive can be started degraded. 376 * Since 2.22 377 * Returns: TRUE if the drive can be started degraded, FALSE otherwise. 378 */ 379 public int canStartDegraded() 380 { 381 // gboolean g_drive_can_start_degraded (GDrive *drive); 382 return g_drive_can_start_degraded(getDriveTStruct()); 383 } 384 385 /** 386 * Checks if a drive can be stopped. 387 * Since 2.22 388 * Returns: TRUE if the drive can be stopped, FALSE otherwise. 389 */ 390 public int canStop() 391 { 392 // gboolean g_drive_can_stop (GDrive *drive); 393 return g_drive_can_stop(getDriveTStruct()); 394 } 395 396 /** 397 * Checks if a drive can be polled for media changes. 398 * Returns: TRUE if the drive can be polled for media changes, FALSE otherwise. 399 */ 400 public int canPollForMedia() 401 { 402 // gboolean g_drive_can_poll_for_media (GDrive *drive); 403 return g_drive_can_poll_for_media(getDriveTStruct()); 404 } 405 406 /** 407 * Asynchronously polls drive to see if media has been inserted or removed. 408 * When the operation is finished, callback will be called. 409 * You can then call g_drive_poll_for_media_finish() to obtain the 410 * result of the operation. 411 * Params: 412 * cancellable = optional GCancellable object, NULL to ignore. [allow-none] 413 * callback = a GAsyncReadyCallback, or NULL. [allow-none] 414 * userData = user data to pass to callback 415 */ 416 public void pollForMedia(Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 417 { 418 // void g_drive_poll_for_media (GDrive *drive, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); 419 g_drive_poll_for_media(getDriveTStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 420 } 421 422 /** 423 * Finishes an operation started with g_drive_poll_for_media() on a drive. 424 * Params: 425 * result = a GAsyncResult. 426 * Returns: TRUE if the drive has been poll_for_mediaed successfully, FALSE otherwise. 427 * Throws: GException on failure. 428 */ 429 public int pollForMediaFinish(AsyncResultIF result) 430 { 431 // gboolean g_drive_poll_for_media_finish (GDrive *drive, GAsyncResult *result, GError **error); 432 GError* err = null; 433 434 auto p = g_drive_poll_for_media_finish(getDriveTStruct(), (result is null) ? null : result.getAsyncResultTStruct(), &err); 435 436 if (err !is null) 437 { 438 throw new GException( new ErrorG(err) ); 439 } 440 441 return p; 442 } 443 444 /** 445 * Checks if the drive has media. Note that the OS may not be polling 446 * the drive for media changes; see g_drive_is_media_check_automatic() 447 * for more details. 448 * Returns: TRUE if drive has media, FALSE otherwise. 449 */ 450 public int hasMedia() 451 { 452 // gboolean g_drive_has_media (GDrive *drive); 453 return g_drive_has_media(getDriveTStruct()); 454 } 455 456 /** 457 * Checks if drive is capabable of automatically detecting media changes. 458 * Returns: TRUE if the drive is capabable of automatically detecting media changes, FALSE otherwise. 459 */ 460 public int isMediaCheckAutomatic() 461 { 462 // gboolean g_drive_is_media_check_automatic (GDrive *drive); 463 return g_drive_is_media_check_automatic(getDriveTStruct()); 464 } 465 466 /** 467 * Checks if the drive supports removable media. 468 * Returns: TRUE if drive supports removable media, FALSE otherwise. 469 */ 470 public int isMediaRemovable() 471 { 472 // gboolean g_drive_is_media_removable (GDrive *drive); 473 return g_drive_is_media_removable(getDriveTStruct()); 474 } 475 476 /** 477 * Warning 478 * g_drive_eject has been deprecated since version 2.22 and should not be used in newly-written code. Use g_drive_eject_with_operation() instead. 479 * Asynchronously ejects a drive. 480 * When the operation is finished, callback will be called. 481 * You can then call g_drive_eject_finish() to obtain the 482 * result of the operation. 483 * Params: 484 * flags = flags affecting the unmount if required for eject 485 * cancellable = optional GCancellable object, NULL to ignore. [allow-none] 486 * callback = a GAsyncReadyCallback, or NULL. [allow-none] 487 * userData = user data to pass to callback 488 */ 489 public void eject(GMountUnmountFlags flags, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 490 { 491 // void g_drive_eject (GDrive *drive, GMountUnmountFlags flags, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); 492 g_drive_eject(getDriveTStruct(), flags, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 493 } 494 495 /** 496 * Warning 497 * g_drive_eject_finish has been deprecated since version 2.22 and should not be used in newly-written code. Use g_drive_eject_with_operation_finish() instead. 498 * Finishes ejecting a drive. 499 * Params: 500 * result = a GAsyncResult. 501 * Returns: TRUE if the drive has been ejected successfully, FALSE otherwise. 502 * Throws: GException on failure. 503 */ 504 public int ejectFinish(AsyncResultIF result) 505 { 506 // gboolean g_drive_eject_finish (GDrive *drive, GAsyncResult *result, GError **error); 507 GError* err = null; 508 509 auto p = g_drive_eject_finish(getDriveTStruct(), (result is null) ? null : result.getAsyncResultTStruct(), &err); 510 511 if (err !is null) 512 { 513 throw new GException( new ErrorG(err) ); 514 } 515 516 return p; 517 } 518 519 /** 520 * Ejects a drive. This is an asynchronous operation, and is 521 * finished by calling g_drive_eject_with_operation_finish() with the drive 522 * and GAsyncResult data returned in the callback. 523 * Since 2.22 524 * Params: 525 * flags = flags affecting the unmount if required for eject 526 * mountOperation = a GMountOperation or NULL to avoid 527 * user interaction. [allow-none] 528 * cancellable = optional GCancellable object, NULL to ignore. [allow-none] 529 * callback = a GAsyncReadyCallback, or NULL. [allow-none] 530 * userData = user data passed to callback. 531 */ 532 public void ejectWithOperation(GMountUnmountFlags flags, MountOperation mountOperation, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 533 { 534 // void g_drive_eject_with_operation (GDrive *drive, GMountUnmountFlags flags, GMountOperation *mount_operation, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); 535 g_drive_eject_with_operation(getDriveTStruct(), flags, (mountOperation is null) ? null : mountOperation.getMountOperationStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 536 } 537 538 /** 539 * Finishes ejecting a drive. If any errors occurred during the operation, 540 * error will be set to contain the errors and FALSE will be returned. 541 * Since 2.22 542 * Params: 543 * result = a GAsyncResult. 544 * Returns: TRUE if the drive was successfully ejected. FALSE otherwise. 545 * Throws: GException on failure. 546 */ 547 public int ejectWithOperationFinish(AsyncResultIF result) 548 { 549 // gboolean g_drive_eject_with_operation_finish (GDrive *drive, GAsyncResult *result, GError **error); 550 GError* err = null; 551 552 auto p = g_drive_eject_with_operation_finish(getDriveTStruct(), (result is null) ? null : result.getAsyncResultTStruct(), &err); 553 554 if (err !is null) 555 { 556 throw new GException( new ErrorG(err) ); 557 } 558 559 return p; 560 } 561 562 /** 563 * Asynchronously starts a drive. 564 * When the operation is finished, callback will be called. 565 * You can then call g_drive_start_finish() to obtain the 566 * result of the operation. 567 * Since 2.22 568 * Params: 569 * flags = flags affecting the start operation. 570 * mountOperation = a GMountOperation or NULL to avoid 571 * user interaction. [allow-none] 572 * cancellable = optional GCancellable object, NULL to ignore. [allow-none] 573 * callback = a GAsyncReadyCallback, or NULL. [allow-none] 574 * userData = user data to pass to callback 575 */ 576 public void start(GDriveStartFlags flags, MountOperation mountOperation, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 577 { 578 // void g_drive_start (GDrive *drive, GDriveStartFlags flags, GMountOperation *mount_operation, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); 579 g_drive_start(getDriveTStruct(), flags, (mountOperation is null) ? null : mountOperation.getMountOperationStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 580 } 581 582 /** 583 * Finishes starting a drive. 584 * Since 2.22 585 * Params: 586 * result = a GAsyncResult. 587 * Returns: TRUE if the drive has been started successfully, FALSE otherwise. 588 * Throws: GException on failure. 589 */ 590 public int startFinish(AsyncResultIF result) 591 { 592 // gboolean g_drive_start_finish (GDrive *drive, GAsyncResult *result, GError **error); 593 GError* err = null; 594 595 auto p = g_drive_start_finish(getDriveTStruct(), (result is null) ? null : result.getAsyncResultTStruct(), &err); 596 597 if (err !is null) 598 { 599 throw new GException( new ErrorG(err) ); 600 } 601 602 return p; 603 } 604 605 /** 606 * Asynchronously stops a drive. 607 * When the operation is finished, callback will be called. 608 * You can then call g_drive_stop_finish() to obtain the 609 * result of the operation. 610 * Since 2.22 611 * Params: 612 * flags = flags affecting the unmount if required for stopping. 613 * mountOperation = a GMountOperation or NULL to avoid 614 * user interaction. [allow-none] 615 * cancellable = optional GCancellable object, NULL to ignore. [allow-none] 616 * callback = a GAsyncReadyCallback, or NULL. [allow-none] 617 * userData = user data to pass to callback 618 */ 619 public void stop(GMountUnmountFlags flags, MountOperation mountOperation, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 620 { 621 // void g_drive_stop (GDrive *drive, GMountUnmountFlags flags, GMountOperation *mount_operation, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); 622 g_drive_stop(getDriveTStruct(), flags, (mountOperation is null) ? null : mountOperation.getMountOperationStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 623 } 624 625 /** 626 * Finishes stopping a drive. 627 * Since 2.22 628 * Params: 629 * result = a GAsyncResult. 630 * Returns: TRUE if the drive has been stopped successfully, FALSE otherwise. 631 * Throws: GException on failure. 632 */ 633 public int stopFinish(AsyncResultIF result) 634 { 635 // gboolean g_drive_stop_finish (GDrive *drive, GAsyncResult *result, GError **error); 636 GError* err = null; 637 638 auto p = g_drive_stop_finish(getDriveTStruct(), (result is null) ? null : result.getAsyncResultTStruct(), &err); 639 640 if (err !is null) 641 { 642 throw new GException( new ErrorG(err) ); 643 } 644 645 return p; 646 } 647 648 /** 649 * Gets the kinds of identifiers that drive has. 650 * Use g_drive_get_identifier() to obtain the identifiers 651 * themselves. 652 * Returns: a NULL-terminated array of strings containing kinds of identifiers. Use g_strfreev() to free. [transfer full][array zero-terminated=1] 653 */ 654 public string[] enumerateIdentifiers() 655 { 656 // char ** g_drive_enumerate_identifiers (GDrive *drive); 657 return Str.toStringArray(g_drive_enumerate_identifiers(getDriveTStruct())); 658 } 659 660 /** 661 * Gets the identifier of the given kind for drive. 662 * Params: 663 * kind = the kind of identifier to return 664 * Returns: a newly allocated string containing the requested identfier, or NULL if the GDrive doesn't have this kind of identifier. 665 */ 666 public string getIdentifier(string kind) 667 { 668 // char * g_drive_get_identifier (GDrive *drive, const char *kind); 669 return Str.toString(g_drive_get_identifier(getDriveTStruct(), Str.toStringz(kind))); 670 } 671 672 /** 673 * Gets the sort key for drive, if any. 674 * Since 2.32 675 * Signal Details 676 * The "changed" signal 677 * void user_function (GDrive *drive, 678 * gpointer user_data) : Run Last 679 * Emitted when the drive's state has changed. 680 * Returns: Sorting key for drive or NULL if no such key is available. 681 */ 682 public string getSortKey() 683 { 684 // const gchar * g_drive_get_sort_key (GDrive *drive); 685 return Str.toString(g_drive_get_sort_key(getDriveTStruct())); 686 } 687 }